b9f592bad5eadd7cbf253f78a759ba044ac6a399
[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 : Clear
657 //purpose  : Remove all the object from the viewer
658 //==============================================================================
659 void ViewerTest::Clear()
660 {
661   if (a3DView().IsNull())
662   {
663     return;
664   }
665
666   NCollection_Sequence<Handle(AIS_InteractiveObject)> aListRemoved;
667   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS()); anObjIter.More(); anObjIter.Next())
668   {
669     const Handle(AIS_InteractiveObject) anObj = anObjIter.Key1();
670     if (anObj->GetContext() != TheAISContext())
671     {
672       continue;
673     }
674
675     std::cout << "Remove " << anObjIter.Key2() << std::endl;
676     TheAISContext()->Remove (anObj, Standard_False);
677     aListRemoved.Append (anObj);
678   }
679
680   TheAISContext()->RebuildSelectionStructs();
681   TheAISContext()->UpdateCurrentViewer();
682   if (aListRemoved.Size() == GetMapOfAIS().Extent())
683   {
684     GetMapOfAIS().Clear();
685   }
686   else
687   {
688     for (NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator anObjIter (aListRemoved); anObjIter.More(); anObjIter.Next())
689     {
690       GetMapOfAIS().UnBind1 (anObjIter.Value());
691     }
692   }
693 }
694
695 //==============================================================================
696 //function : CopyIsoAspect
697 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
698 //==============================================================================
699 static Handle(Prs3d_IsoAspect) CopyIsoAspect
700       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
701        const Standard_Integer theNbIsos)
702 {
703   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
704   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
705   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
706
707   Handle(Prs3d_IsoAspect) aResult =
708     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
709
710   return aResult;
711 }
712
713 //==============================================================================
714 //function : visos
715 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
716 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
717 //==============================================================================
718 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
719 {
720   if (TheAISContext().IsNull()) {
721     di << argv[0] << " Call 'vinit' before!\n";
722     return 1;
723   }
724
725   if (argc <= 1) {
726     di << "Current number of isos : " <<
727       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
728       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
729     di << "IsoOnPlane mode is " <<
730       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
731     di << "IsoOnTriangulation mode is " <<
732       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
733     return 0;
734   }
735
736   Standard_Integer aLastInd = argc - 1;
737   Standard_Boolean isChanged = Standard_False;
738   Standard_Integer aNbUIsos = 0;
739   Standard_Integer aNbVIsos = 0;
740
741   if (aLastInd >= 3) {
742     Standard_Boolean isIsoOnPlane = Standard_False;
743
744     if (strcmp(argv[aLastInd], "1") == 0) {
745       isIsoOnPlane = Standard_True;
746       isChanged    = Standard_True;
747     } else if (strcmp(argv[aLastInd], "0") == 0) {
748       isIsoOnPlane = Standard_False;
749       isChanged    = Standard_True;
750     }
751
752     if (isChanged) {
753       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
754       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
755       aLastInd -= 3;
756
757       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
758       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
759
760       TheAISContext()->IsoOnPlane(isIsoOnPlane);
761
762       if (aLastInd == 0) {
763         // If there are no shapes provided set the default numbers.
764         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
765         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
766       }
767     }
768   }
769
770   Standard_Integer i;
771
772   for (i = 1; i <= aLastInd; i++)
773   {
774     TCollection_AsciiString name(argv[i]);
775     Handle(AIS_InteractiveObject) aShape;
776     GetMapOfAIS().Find2(name, aShape);
777     if (aShape.IsNull())
778     {
779       std::cout << "Syntax error: object '" << name << "' is not found\n";
780       return 1;
781     }
782
783     Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
784     Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
785     Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
786     if (isChanged)
787     {
788       CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
789       CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
790       TheAISContext()->SetLocalAttributes (aShape, CurDrawer, Standard_False);
791       TheAISContext()->Redisplay (aShape, Standard_False);
792     }
793     else
794     {
795       di << "Number of isos for " << argv[i] << " : "
796           << aUIso->Number() << " " << aVIso->Number() << "\n";
797     }
798   }
799
800   if (isChanged) {
801     TheAISContext()->UpdateCurrentViewer();
802   }
803
804   return 0;
805 }
806
807 static Standard_Integer VDispSensi (Draw_Interpretor& ,
808                                     Standard_Integer  theArgNb,
809                                     Standard_CString* )
810 {
811   if (theArgNb > 1)
812   {
813     std::cout << "Error: wrong syntax!\n";
814     return 1;
815   }
816
817   Handle(AIS_InteractiveContext) aCtx;
818   Handle(V3d_View)               aView;
819   if (!getCtxAndView (aCtx, aView))
820   {
821     return 1;
822   }
823
824   aCtx->DisplayActiveSensitive (aView);
825   return 0;
826
827 }
828
829 static Standard_Integer VClearSensi (Draw_Interpretor& ,
830                                      Standard_Integer  theArgNb,
831                                      Standard_CString* )
832 {
833   if (theArgNb > 1)
834   {
835     std::cout << "Error: wrong syntax!\n";
836     return 1;
837   }
838
839   Handle(AIS_InteractiveContext) aCtx;
840   Handle(V3d_View)               aView;
841   if (!getCtxAndView (aCtx, aView))
842   {
843     return 1;
844   }
845   aCtx->ClearActiveSensitive (aView);
846   return 0;
847 }
848
849 //==============================================================================
850 //function : VDir
851 //purpose  : To list the displayed object with their attributes
852 //==============================================================================
853 static int VDir (Draw_Interpretor& theDI,
854                  Standard_Integer ,
855                  const char** )
856 {
857   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
858        anIter.More(); anIter.Next())
859   {
860     theDI << "\t" << anIter.Key2() << "\n";
861   }
862   return 0;
863 }
864
865 //! Auxiliary enumeration
866 enum ViewerTest_StereoPair
867 {
868   ViewerTest_SP_Single,
869   ViewerTest_SP_SideBySide,
870   ViewerTest_SP_OverUnder
871 };
872
873 //==============================================================================
874 //function : VDump
875 //purpose  : To dump the active view snapshot to image file
876 //==============================================================================
877 static Standard_Integer VDump (Draw_Interpretor& theDI,
878                                Standard_Integer  theArgNb,
879                                Standard_CString* theArgVec)
880 {
881   if (theArgNb < 2)
882   {
883     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
884     return 1;
885   }
886
887   Standard_Integer      anArgIter   = 1;
888   Standard_CString      aFilePath   = theArgVec[anArgIter++];
889   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
890   V3d_ImageDumpOptions  aParams;
891   aParams.BufferType    = Graphic3d_BT_RGB;
892   aParams.StereoOptions = V3d_SDO_MONO;
893   for (; anArgIter < theArgNb; ++anArgIter)
894   {
895     TCollection_AsciiString anArg (theArgVec[anArgIter]);
896     anArg.LowerCase();
897     if (anArg == "-buffer")
898     {
899       if (++anArgIter >= theArgNb)
900       {
901         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
902         return 1;
903       }
904
905       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
906       aBufArg.LowerCase();
907       if (aBufArg == "rgba")
908       {
909         aParams.BufferType = Graphic3d_BT_RGBA;
910       }
911       else if (aBufArg == "rgb")
912       {
913         aParams.BufferType = Graphic3d_BT_RGB;
914       }
915       else if (aBufArg == "depth")
916       {
917         aParams.BufferType = Graphic3d_BT_Depth;
918       }
919       else
920       {
921         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
922         return 1;
923       }
924     }
925     else if (anArg == "-stereo")
926     {
927       if (++anArgIter >= theArgNb)
928       {
929         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
930         return 1;
931       }
932
933       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
934       aStereoArg.LowerCase();
935       if (aStereoArg == "l"
936        || aStereoArg == "left")
937       {
938         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
939       }
940       else if (aStereoArg == "r"
941             || aStereoArg == "right")
942       {
943         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
944       }
945       else if (aStereoArg == "mono")
946       {
947         aParams.StereoOptions = V3d_SDO_MONO;
948       }
949       else if (aStereoArg == "blended"
950             || aStereoArg == "blend"
951             || aStereoArg == "stereo")
952       {
953         aParams.StereoOptions = V3d_SDO_BLENDED;
954       }
955       else if (aStereoArg == "sbs"
956             || aStereoArg == "sidebyside")
957       {
958         aStereoPair = ViewerTest_SP_SideBySide;
959       }
960       else if (aStereoArg == "ou"
961             || aStereoArg == "overunder")
962       {
963         aStereoPair = ViewerTest_SP_OverUnder;
964       }
965       else
966       {
967         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
968         return 1;
969       }
970     }
971     else if (anArg == "-rgba"
972           || anArg ==  "rgba")
973     {
974       aParams.BufferType = Graphic3d_BT_RGBA;
975     }
976     else if (anArg == "-rgb"
977           || anArg ==  "rgb")
978     {
979       aParams.BufferType = Graphic3d_BT_RGB;
980     }
981     else if (anArg == "-depth"
982           || anArg ==  "depth")
983     {
984       aParams.BufferType = Graphic3d_BT_Depth;
985     }
986     else if (anArg == "-width"
987           || anArg ==  "width"
988           || anArg ==  "sizex")
989     {
990       if (aParams.Width != 0)
991       {
992         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
993         return 1;
994       }
995       else if (++anArgIter >= theArgNb)
996       {
997         std::cout << "Error: integer value is expected right after 'width'\n";
998         return 1;
999       }
1000       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
1001     }
1002     else if (anArg == "-height"
1003           || anArg ==  "height"
1004           || anArg ==  "-sizey")
1005     {
1006       if (aParams.Height != 0)
1007       {
1008         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1009         return 1;
1010       }
1011       else if (++anArgIter >= theArgNb)
1012       {
1013         std::cout << "Error: integer value is expected right after 'height'\n";
1014         return 1;
1015       }
1016       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
1017     }
1018     else if (anArg == "-tile"
1019           || anArg == "-tilesize")
1020     {
1021       if (++anArgIter >= theArgNb)
1022       {
1023         std::cout << "Error: integer value is expected right after 'tileSize'\n";
1024         return 1;
1025       }
1026       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
1027     }
1028     else
1029     {
1030       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
1031       return 1;
1032     }
1033   }
1034   if ((aParams.Width <= 0 && aParams.Height >  0)
1035    || (aParams.Width >  0 && aParams.Height <= 0))
1036   {
1037     std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
1038     return 1;
1039   }
1040
1041   Handle(V3d_View) aView = ViewerTest::CurrentView();
1042   if (aView.IsNull())
1043   {
1044     std::cout << "Error: cannot find an active view!\n";
1045     return 1;
1046   }
1047
1048   if (aParams.Width <= 0 || aParams.Height <= 0)
1049   {
1050     aView->Window()->Size (aParams.Width, aParams.Height);
1051   }
1052
1053   Image_AlienPixMap aPixMap;
1054   Image_Format aFormat = Image_Format_UNKNOWN;
1055   switch (aParams.BufferType)
1056   {
1057     case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
1058     case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
1059     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
1060     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
1061   }
1062
1063   switch (aStereoPair)
1064   {
1065     case ViewerTest_SP_Single:
1066     {
1067       if (!aView->ToPixMap (aPixMap, aParams))
1068       {
1069         theDI << "Fail: view dump failed!\n";
1070         return 0;
1071       }
1072       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
1073             || aPixMap.SizeY() != Standard_Size(aParams.Height))
1074       {
1075         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
1076               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
1077       }
1078       break;
1079     }
1080     case ViewerTest_SP_SideBySide:
1081     {
1082       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
1083       {
1084         theDI << "Fail: not enough memory for image allocation!\n";
1085         return 0;
1086       }
1087
1088       Image_PixMap aPixMapL, aPixMapR;
1089       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1090                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1091       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1092                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1093
1094       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1095       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1096       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1097       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1098       if (!isOk)
1099       {
1100         theDI << "Fail: view dump failed!\n";
1101         return 0;
1102       }
1103       break;
1104     }
1105     case ViewerTest_SP_OverUnder:
1106     {
1107       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1108       {
1109         theDI << "Fail: not enough memory for image allocation!\n";
1110         return 0;
1111       }
1112
1113       Image_PixMap aPixMapL, aPixMapR;
1114       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1115                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1116       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1117                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1118
1119       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1120       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1121       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1122       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1123       if (!isOk)
1124       {
1125         theDI << "Fail: view dump failed!\n";
1126         return 0;
1127       }
1128       break;
1129     }
1130   }
1131
1132   if (!aPixMap.Save (aFilePath))
1133   {
1134     theDI << "Fail: image can not be saved!\n";
1135   }
1136   return 0;
1137 }
1138
1139 enum TypeOfDispOperation
1140 {
1141   TypeOfDispOperation_SetDispMode,
1142   TypeOfDispOperation_UnsetDispMode
1143 };
1144
1145 //! Displays,Erase...
1146 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1147                                                 const Standard_Integer theMode,
1148                                                 const TypeOfDispOperation theType,
1149                                                 const Standard_Boolean theToUpdate)
1150 {
1151   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1152   switch (theType)
1153   {
1154     case TypeOfDispOperation_SetDispMode:
1155     {
1156       if (!thePrs.IsNull())
1157       {
1158         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1159       }
1160       else
1161       {
1162         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1163       }
1164       break;
1165     }
1166     case TypeOfDispOperation_UnsetDispMode:
1167     {
1168       if (!thePrs.IsNull())
1169       {
1170         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1171       }
1172       else
1173       {
1174         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1175       }
1176       break;
1177     }
1178   }
1179 }
1180
1181 //=======================================================================
1182 //function :
1183 //purpose  :
1184 //=======================================================================
1185 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1186 {
1187   if (argc < 1
1188    || argc > 3)
1189   {
1190     std::cout << "Syntax error: wrong number of arguments\n";
1191     return 1;
1192   }
1193
1194   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1195                             ? TypeOfDispOperation_UnsetDispMode
1196                             : TypeOfDispOperation_SetDispMode;
1197   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1198   if (aType == TypeOfDispOperation_UnsetDispMode)
1199   {
1200     if (argc == 1)
1201     {
1202       if (aCtx->NbSelected() == 0)
1203       {
1204         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1205       }
1206       else
1207       {
1208         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1209         {
1210           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1211         }
1212       }
1213       aCtx->UpdateCurrentViewer();
1214     }
1215     else
1216     {
1217       TCollection_AsciiString aName = argv[1];
1218       Handle(AIS_InteractiveObject) aPrs;
1219       if (GetMapOfAIS().Find2 (aName, aPrs)
1220       && !aPrs.IsNull())
1221       {
1222         VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1223       }
1224     }
1225   }
1226   else if (argc == 2)
1227   {
1228     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1229     if (aCtx->NbSelected() == 0
1230      && aType == TypeOfDispOperation_SetDispMode)
1231     {
1232       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1233     }
1234     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1235     {
1236       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1237     }
1238     aCtx->UpdateCurrentViewer();
1239   }
1240   else
1241   {
1242     Handle(AIS_InteractiveObject) aPrs;
1243     TCollection_AsciiString aName (argv[1]);
1244     if (GetMapOfAIS().Find2 (aName, aPrs)
1245      && !aPrs.IsNull())
1246     {
1247       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1248     }
1249   }
1250   return 0;
1251 }
1252
1253
1254 //=======================================================================
1255 //function :
1256 //purpose  :
1257 //=======================================================================
1258 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1259 {
1260   if(argc==1) return 1;
1261   Standard_Integer On = Draw::Atoi(argv[1]);
1262   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1263
1264   if(argc==2)
1265   {
1266     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1267     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1268     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1269     {
1270       if(On==1)
1271       {
1272         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1273       }
1274       else
1275       {
1276         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1277       }
1278     }
1279
1280     Ctx->UpdateCurrentViewer();
1281   }
1282   else {
1283     Handle(AIS_InteractiveObject) IO;
1284     TCollection_AsciiString name = argv[2];
1285     if (GetMapOfAIS().Find2 (name, IO)
1286     && !IO.IsNull())
1287     {
1288       if(On==1)
1289         Ctx->SubIntensityOn(IO, Standard_True);
1290       else
1291         Ctx->SubIntensityOff(IO, Standard_True);
1292     }
1293     else return 1;
1294   }
1295   return 0;
1296 }
1297
1298 //! Auxiliary class to iterate presentations from different collections.
1299 class ViewTest_PrsIter
1300 {
1301 public:
1302
1303   //! Create and initialize iterator object.
1304   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1305   : mySource (IterSource_All)
1306   {
1307     NCollection_Sequence<TCollection_AsciiString> aNames;
1308     if (!theName.IsEmpty())
1309     aNames.Append (theName);
1310     Init (aNames);
1311   }
1312
1313   //! Create and initialize iterator object.
1314   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1315   : mySource (IterSource_All)
1316   {
1317     Init (theNames);
1318   }
1319
1320   //! Initialize the iterator.
1321   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1322   {
1323     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1324     mySeq = theNames;
1325     mySelIter.Nullify();
1326     myCurrent.Nullify();
1327     myCurrentTrs.Nullify();
1328     if (!mySeq.IsEmpty())
1329     {
1330       mySource = IterSource_List;
1331       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1332     }
1333     else if (aCtx->NbSelected() > 0)
1334     {
1335       mySource  = IterSource_Selected;
1336       mySelIter = aCtx;
1337       mySelIter->InitSelected();
1338     }
1339     else
1340     {
1341       mySource = IterSource_All;
1342       myMapIter.Initialize (GetMapOfAIS());
1343     }
1344     initCurrent();
1345   }
1346
1347   const TCollection_AsciiString& CurrentName() const
1348   {
1349     return myCurrentName;
1350   }
1351
1352   const Handle(AIS_InteractiveObject)& Current() const
1353   {
1354     return myCurrent;
1355   }
1356
1357   const Handle(Standard_Transient)& CurrentTrs() const
1358   {
1359     return myCurrentTrs;
1360   }
1361
1362   //! @return true if iterator points to valid object within collection
1363   Standard_Boolean More() const
1364   {
1365     switch (mySource)
1366     {
1367       case IterSource_All:      return myMapIter.More();
1368       case IterSource_List:     return mySeqIter.More();
1369       case IterSource_Selected: return mySelIter->MoreSelected();
1370     }
1371     return Standard_False;
1372   }
1373
1374   //! Go to the next item.
1375   void Next()
1376   {
1377     myCurrentName.Clear();
1378     myCurrentTrs.Nullify();
1379     myCurrent.Nullify();
1380     switch (mySource)
1381     {
1382       case IterSource_All:
1383       {
1384         myMapIter.Next();
1385         break;
1386       }
1387       case IterSource_List:
1388       {
1389         mySeqIter.Next();
1390         break;
1391       }
1392       case IterSource_Selected:
1393       {
1394         mySelIter->NextSelected();
1395         break;
1396       }
1397     }
1398     initCurrent();
1399   }
1400
1401 private:
1402
1403   void initCurrent()
1404   {
1405     switch (mySource)
1406     {
1407       case IterSource_All:
1408       {
1409         if (myMapIter.More())
1410         {
1411           myCurrentName = myMapIter.Key2();
1412           myCurrentTrs  = myMapIter.Key1();
1413           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1414         }
1415         break;
1416       }
1417       case IterSource_List:
1418       {
1419         if (mySeqIter.More())
1420         {
1421           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1422           {
1423             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1424             return;
1425           }
1426           myCurrentName = mySeqIter.Value();
1427           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1428           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1429         }
1430         break;
1431       }
1432       case IterSource_Selected:
1433       {
1434         if (mySelIter->MoreSelected())
1435         {
1436           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1437           myCurrent     = mySelIter->SelectedInteractive();
1438         }
1439         break;
1440       }
1441     }
1442   }
1443
1444 private:
1445
1446   enum IterSource
1447   {
1448     IterSource_All,
1449     IterSource_List,
1450     IterSource_Selected
1451   };
1452
1453 private:
1454
1455   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1456   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1457   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1458   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1459
1460   TCollection_AsciiString        myCurrentName;//!< current item name
1461   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1462   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1463
1464   IterSource                     mySource;     //!< iterated collection
1465
1466 };
1467
1468 //! Parse interior style name.
1469 static bool parseInteriorStyle (const TCollection_AsciiString& theArg,
1470                                 Aspect_InteriorStyle& theStyle)
1471 {
1472   TCollection_AsciiString anArg (theArg);
1473   anArg.LowerCase();
1474   if (anArg == "empty")
1475   {
1476     theStyle = Aspect_IS_EMPTY;
1477   }
1478   else if (anArg == "hollow")
1479   {
1480     theStyle = Aspect_IS_HOLLOW;
1481   }
1482   else if (anArg == "solid")
1483   {
1484     theStyle = Aspect_IS_SOLID;
1485   }
1486   else if (anArg == "hatch")
1487   {
1488     theStyle = Aspect_IS_HATCH;
1489   }
1490   else if (anArg == "hiddenline"
1491         || anArg == "hidden-line"
1492         || anArg == "hidden_line")
1493   {
1494     theStyle = Aspect_IS_HIDDENLINE;
1495   }
1496   else if (anArg == "point")
1497   {
1498     theStyle = Aspect_IS_POINT;
1499   }
1500   else if (theArg.IsIntegerValue())
1501   {
1502     const Standard_Integer anIntStyle = theArg.IntegerValue();
1503     if (anIntStyle < Aspect_IS_EMPTY || anIntStyle > Aspect_IS_POINT)
1504     {
1505       return false;
1506     }
1507     theStyle = (Aspect_InteriorStyle)anIntStyle;
1508   }
1509   else
1510   {
1511     return false;
1512   }
1513   return true;
1514 }
1515
1516 //! Auxiliary structure for VAspects
1517 struct ViewerTest_AspectsChangeSet
1518 {
1519   Standard_Integer             ToSetVisibility;
1520   Standard_Integer             Visibility;
1521
1522   Standard_Integer             ToSetColor;
1523   Quantity_Color               Color;
1524
1525   Standard_Integer             ToSetLineWidth;
1526   Standard_Real                LineWidth;
1527
1528   Standard_Integer             ToSetTypeOfLine;
1529   Aspect_TypeOfLine            TypeOfLine;
1530
1531   Standard_Integer             ToSetTypeOfMarker;
1532   Aspect_TypeOfMarker          TypeOfMarker;
1533   Handle(Image_PixMap)         MarkerImage;
1534
1535   Standard_Integer             ToSetMarkerSize;
1536   Standard_Real                MarkerSize;
1537
1538   Standard_Integer             ToSetTransparency;
1539   Standard_Real                Transparency;
1540
1541   Standard_Integer             ToSetAlphaMode;
1542   Graphic3d_AlphaMode          AlphaMode;
1543   Standard_ShortReal           AlphaCutoff;
1544
1545   Standard_Integer             ToSetMaterial;
1546   Graphic3d_NameOfMaterial     Material;
1547   TCollection_AsciiString      MatName;
1548
1549   NCollection_Sequence<TopoDS_Shape> SubShapes;
1550
1551   Standard_Integer             ToSetShowFreeBoundary;
1552   Standard_Integer             ToSetFreeBoundaryWidth;
1553   Standard_Real                FreeBoundaryWidth;
1554   Standard_Integer             ToSetFreeBoundaryColor;
1555   Quantity_Color               FreeBoundaryColor;
1556
1557   Standard_Integer             ToEnableIsoOnTriangulation;
1558
1559   Standard_Integer             ToSetMaxParamValue;
1560   Standard_Real                MaxParamValue;
1561
1562   Standard_Integer             ToSetSensitivity;
1563   Standard_Integer             SelectionMode;
1564   Standard_Integer             Sensitivity;
1565
1566   Standard_Integer             ToSetHatch;
1567   Standard_Integer             StdHatchStyle;
1568   TCollection_AsciiString      PathToHatchPattern;
1569
1570   Standard_Integer             ToSetShadingModel;
1571   Graphic3d_TypeOfShadingModel ShadingModel;
1572   TCollection_AsciiString      ShadingModelName;
1573
1574   Standard_Integer             ToSetInterior;
1575   Aspect_InteriorStyle         InteriorStyle;
1576
1577   Standard_Integer             ToSetDrawEdges;
1578   Standard_Integer             ToSetQuadEdges;
1579
1580   Standard_Integer             ToSetEdgeColor;
1581   Quantity_ColorRGBA           EdgeColor;
1582
1583   Standard_Integer             ToSetEdgeWidth;
1584   Standard_Real                EdgeWidth;
1585
1586   Standard_Integer             ToSetTypeOfEdge;
1587   Aspect_TypeOfLine            TypeOfEdge;
1588
1589   //! Empty constructor
1590   ViewerTest_AspectsChangeSet()
1591   : ToSetVisibility   (0),
1592     Visibility        (1),
1593     ToSetColor        (0),
1594     Color             (DEFAULT_COLOR),
1595     ToSetLineWidth    (0),
1596     LineWidth         (1.0),
1597     ToSetTypeOfLine   (0),
1598     TypeOfLine        (Aspect_TOL_SOLID),
1599     ToSetTypeOfMarker (0),
1600     TypeOfMarker      (Aspect_TOM_PLUS),
1601     ToSetMarkerSize   (0),
1602     MarkerSize        (1.0),
1603     ToSetTransparency (0),
1604     Transparency      (0.0),
1605     ToSetAlphaMode    (0),
1606     AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
1607     AlphaCutoff       (0.5f),
1608     ToSetMaterial     (0),
1609     Material          (Graphic3d_NOM_DEFAULT),
1610     ToSetShowFreeBoundary      (0),
1611     ToSetFreeBoundaryWidth     (0),
1612     FreeBoundaryWidth          (1.0),
1613     ToSetFreeBoundaryColor     (0),
1614     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1615     ToEnableIsoOnTriangulation (-1),
1616     ToSetMaxParamValue         (0),
1617     MaxParamValue              (500000),
1618     ToSetSensitivity           (0),
1619     SelectionMode              (-1),
1620     Sensitivity                (-1),
1621     ToSetHatch                 (0),
1622     StdHatchStyle              (-1),
1623     ToSetShadingModel          (0),
1624     ShadingModel               (Graphic3d_TOSM_DEFAULT),
1625     ToSetInterior              (0),
1626     InteriorStyle              (Aspect_IS_SOLID),
1627     ToSetDrawEdges    (0),
1628     ToSetQuadEdges    (0),
1629     ToSetEdgeColor    (0),
1630     ToSetEdgeWidth    (0),
1631     EdgeWidth         (1.0),
1632     ToSetTypeOfEdge   (0),
1633     TypeOfEdge        (Aspect_TOL_SOLID)
1634     {}
1635
1636   //! @return true if no changes have been requested
1637   Standard_Boolean IsEmpty() const
1638   {
1639     return ToSetVisibility        == 0
1640         && ToSetLineWidth         == 0
1641         && ToSetTransparency      == 0
1642         && ToSetAlphaMode         == 0
1643         && ToSetColor             == 0
1644         && ToSetMaterial          == 0
1645         && ToSetShowFreeBoundary  == 0
1646         && ToSetFreeBoundaryColor == 0
1647         && ToSetFreeBoundaryWidth == 0
1648         && ToSetMaxParamValue     == 0
1649         && ToSetSensitivity       == 0
1650         && ToSetHatch             == 0
1651         && ToSetShadingModel      == 0
1652         && ToSetInterior          == 0
1653         && ToSetDrawEdges         == 0
1654         && ToSetQuadEdges         == 0
1655         && ToSetEdgeColor         == 0
1656         && ToSetEdgeWidth         == 0
1657         && ToSetTypeOfEdge        == 0;
1658   }
1659
1660   //! @return true if properties are valid
1661   Standard_Boolean Validate() const
1662   {
1663     Standard_Boolean isOk = Standard_True;
1664     if (Visibility != 0 && Visibility != 1)
1665     {
1666       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1667       isOk = Standard_False;
1668     }
1669     if (LineWidth <= 0.0
1670      || LineWidth >  10.0)
1671     {
1672       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1673       isOk = Standard_False;
1674     }
1675     if (Transparency < 0.0
1676      || Transparency > 1.0)
1677     {
1678       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1679       isOk = Standard_False;
1680     }
1681     if (ToSetAlphaMode == 1
1682      && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
1683     {
1684       std::cout << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")\n";
1685       isOk = Standard_False;
1686     }
1687     if (ToSetMaterial == 1
1688      && Material == Graphic3d_NOM_DEFAULT)
1689     {
1690       std::cout << "Error: unknown material " << MatName << ".\n";
1691       isOk = Standard_False;
1692     }
1693     if (FreeBoundaryWidth <= 0.0
1694      || FreeBoundaryWidth >  10.0)
1695     {
1696       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1697       isOk = Standard_False;
1698     }
1699     if (MaxParamValue < 0.0)
1700     {
1701       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1702       isOk = Standard_False;
1703     }
1704     if (Sensitivity <= 0 && ToSetSensitivity)
1705     {
1706       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1707       isOk = Standard_False;
1708     }
1709     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1710     {
1711       std::cout << "Error: hatch style must be specified\n";
1712       isOk = Standard_False;
1713     }
1714     if (ToSetShadingModel == 1
1715     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_FRAGMENT))
1716     {
1717       std::cout << "Error: unknown shading model " << ShadingModelName << ".\n";
1718       isOk = Standard_False;
1719     }
1720     return isOk;
1721   }
1722
1723   //! Apply aspects to specified drawer.
1724   bool Apply (const Handle(Prs3d_Drawer)& theDrawer)
1725   {
1726     bool toRecompute = false;
1727     const Handle(Prs3d_Drawer)& aDefDrawer = ViewerTest::GetAISContext()->DefaultDrawer();
1728     if (ToSetShowFreeBoundary != 0)
1729     {
1730       theDrawer->SetFreeBoundaryDraw (ToSetShowFreeBoundary == 1);
1731       toRecompute = true;
1732     }
1733     if (ToSetFreeBoundaryWidth != 0)
1734     {
1735       if (ToSetFreeBoundaryWidth != -1
1736        || theDrawer->HasOwnFreeBoundaryAspect())
1737       {
1738         if (!theDrawer->HasOwnFreeBoundaryAspect())
1739         {
1740           Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
1741           *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
1742           theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
1743           toRecompute = true;
1744         }
1745         theDrawer->FreeBoundaryAspect()->SetWidth (FreeBoundaryWidth);
1746       }
1747     }
1748     if (ToSetFreeBoundaryColor != 0)
1749     {
1750       Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
1751       *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
1752       aBoundaryAspect->SetColor (FreeBoundaryColor);
1753       theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
1754       toRecompute = true;
1755     }
1756     if (ToSetTypeOfLine != 0)
1757     {
1758       if (ToSetTypeOfLine != -1
1759        || theDrawer->HasOwnLineAspect()
1760        || theDrawer->HasOwnWireAspect()
1761        || theDrawer->HasOwnFreeBoundaryAspect()
1762        || theDrawer->HasOwnUnFreeBoundaryAspect()
1763        || theDrawer->HasOwnSeenLineAspect())
1764       {
1765         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
1766         theDrawer->LineAspect()->SetTypeOfLine           (TypeOfLine);
1767         theDrawer->WireAspect()->SetTypeOfLine           (TypeOfLine);
1768         theDrawer->FreeBoundaryAspect()->SetTypeOfLine   (TypeOfLine);
1769         theDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (TypeOfLine);
1770         theDrawer->SeenLineAspect()->SetTypeOfLine       (TypeOfLine);
1771       }
1772     }
1773     if (ToSetTypeOfMarker != 0)
1774     {
1775       if (ToSetTypeOfMarker != -1
1776        || theDrawer->HasOwnPointAspect())
1777       {
1778         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
1779         theDrawer->PointAspect()->SetTypeOfMarker (TypeOfMarker);
1780         theDrawer->PointAspect()->Aspect()->SetMarkerImage (MarkerImage.IsNull() ? Handle(Graphic3d_MarkerImage)() : new Graphic3d_MarkerImage (MarkerImage));
1781       }
1782     }
1783     if (ToSetMarkerSize != 0)
1784     {
1785       if (ToSetMarkerSize != -1
1786        || theDrawer->HasOwnPointAspect())
1787       {
1788         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
1789         theDrawer->PointAspect()->SetScale (MarkerSize);
1790         toRecompute = true;
1791       }
1792     }
1793     if (ToSetMaxParamValue != 0)
1794     {
1795       if (ToSetMaxParamValue != -1
1796        || theDrawer->HasOwnMaximalParameterValue())
1797       {
1798         theDrawer->SetMaximalParameterValue (MaxParamValue);
1799         toRecompute = true;
1800       }
1801     }
1802     if (ToSetShadingModel != 0)
1803     {
1804       if (ToSetShadingModel != -1
1805        || theDrawer->HasOwnShadingAspect())
1806       {
1807         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1808         theDrawer->ShadingAspect()->Aspect()->SetShadingModel (ShadingModel);
1809       }
1810     }
1811     if (ToSetAlphaMode != 0)
1812     {
1813       if (ToSetAlphaMode != -1
1814        || theDrawer->HasOwnShadingAspect())
1815       {
1816         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1817         theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
1818       }
1819     }
1820     if (ToSetHatch != 0)
1821     {
1822       if (ToSetHatch != -1
1823       ||  theDrawer->HasOwnShadingAspect())
1824       {
1825         theDrawer->SetupOwnShadingAspect (aDefDrawer);
1826         Handle(Graphic3d_AspectFillArea3d) anAsp = theDrawer->ShadingAspect()->Aspect();
1827         if (ToSetHatch == -1)
1828         {
1829           anAsp->SetInteriorStyle (Aspect_IS_SOLID);
1830         }
1831         else
1832         {
1833           anAsp->SetInteriorStyle (Aspect_IS_HATCH);
1834           if (!PathToHatchPattern.IsEmpty())
1835           {
1836             Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
1837             if (anImage->Load (TCollection_AsciiString (PathToHatchPattern.ToCString())))
1838             {
1839               anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
1840             }
1841             else
1842             {
1843               std::cout << "Error: cannot load the following image: " << PathToHatchPattern << "\n";
1844             }
1845           }
1846           else if (StdHatchStyle != -1)
1847           {
1848             anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)StdHatchStyle));
1849           }
1850         }
1851         toRecompute = true;
1852       }
1853     }
1854     if (ToSetInterior != 0)
1855     {
1856       if (ToSetInterior != -1
1857        || theDrawer->HasOwnShadingAspect())
1858       {
1859         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1860         theDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (InteriorStyle);
1861         if (InteriorStyle == Aspect_IS_HATCH
1862          && theDrawer->ShadingAspect()->Aspect()->HatchStyle().IsNull())
1863         {
1864           theDrawer->ShadingAspect()->Aspect()->SetHatchStyle (Aspect_HS_VERTICAL);
1865         }
1866       }
1867     }
1868     if (ToSetDrawEdges != 0)
1869     {
1870       if (ToSetDrawEdges != -1
1871        || theDrawer->HasOwnShadingAspect())
1872       {
1873         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1874         theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetDrawEdges == 1);
1875       }
1876     }
1877     if (ToSetQuadEdges != 0)
1878     {
1879       if (ToSetQuadEdges != -1
1880           || theDrawer->HasOwnShadingAspect())
1881       {
1882         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1883         theDrawer->ShadingAspect()->Aspect()->SetSkipFirstEdge (ToSetQuadEdges == 1);
1884       }
1885     }
1886     if (ToSetEdgeWidth != 0)
1887     {
1888       if (ToSetEdgeWidth != -1
1889        || theDrawer->HasOwnShadingAspect())
1890       {
1891         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1892         theDrawer->ShadingAspect()->Aspect()->SetEdgeWidth (EdgeWidth);
1893       }
1894     }
1895     if (ToSetTypeOfEdge != 0)
1896     {
1897       if (ToSetTypeOfEdge != -1
1898        || theDrawer->HasOwnShadingAspect())
1899       {
1900         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1901         theDrawer->ShadingAspect()->Aspect()->SetEdgeLineType (TypeOfEdge);
1902         if (ToSetInterior == 0)
1903         {
1904           theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetTypeOfEdge == 1
1905                                                            && TypeOfEdge != Aspect_TOL_EMPTY);
1906         }
1907       }
1908     }
1909     if (ToSetEdgeColor != 0)
1910     {
1911       if (ToSetEdgeColor != -1
1912        || theDrawer->HasOwnShadingAspect())
1913       {
1914         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
1915         if (ToSetEdgeColor == -1)
1916         {
1917           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (theDrawer->ShadingAspect()->Aspect()->InteriorColor());
1918         }
1919         else
1920         {
1921           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (EdgeColor);
1922         }
1923       }
1924     }
1925     return toRecompute;
1926   }
1927 };
1928
1929 //==============================================================================
1930 //function : VAspects
1931 //purpose  :
1932 //==============================================================================
1933 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
1934                                   Standard_Integer  theArgNb,
1935                                   const char**      theArgVec)
1936 {
1937   TCollection_AsciiString aCmdName (theArgVec[0]);
1938   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1939   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1940   if (aCtx.IsNull())
1941   {
1942     std::cerr << "Error: no active view!\n";
1943     return 1;
1944   }
1945
1946   Standard_Integer anArgIter = 1;
1947   Standard_Boolean isDefaults = Standard_False;
1948   NCollection_Sequence<TCollection_AsciiString> aNames;
1949   for (; anArgIter < theArgNb; ++anArgIter)
1950   {
1951     TCollection_AsciiString anArg = theArgVec[anArgIter];
1952     if (anUpdateTool.parseRedrawMode (anArg))
1953     {
1954       continue;
1955     }
1956     else if (!anArg.IsEmpty()
1957            && anArg.Value (1) != '-')
1958     {
1959       aNames.Append (anArg);
1960     }
1961     else
1962     {
1963       if (anArg == "-defaults")
1964       {
1965         isDefaults = Standard_True;
1966         ++anArgIter;
1967       }
1968       break;
1969     }
1970   }
1971
1972   if (!aNames.IsEmpty() && isDefaults)
1973   {
1974     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
1975     return 1;
1976   }
1977
1978   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
1979   aChanges.Append (ViewerTest_AspectsChangeSet());
1980   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
1981
1982   // parse syntax of legacy commands
1983   bool toParseAliasArgs = false;
1984   if (aCmdName == "vsetwidth")
1985   {
1986     if (aNames.IsEmpty()
1987     || !aNames.Last().IsRealValue())
1988     {
1989       std::cout << "Error: not enough arguments!\n";
1990       return 1;
1991     }
1992     aChangeSet->ToSetLineWidth = 1;
1993     aChangeSet->LineWidth = aNames.Last().RealValue();
1994     aNames.Remove (aNames.Length());
1995   }
1996   else if (aCmdName == "vunsetwidth")
1997   {
1998     aChangeSet->ToSetLineWidth = -1;
1999   }
2000   else if (aCmdName == "vsetcolor")
2001   {
2002     if (aNames.IsEmpty())
2003     {
2004       std::cout << "Error: not enough arguments!\n";
2005       return 1;
2006     }
2007     aChangeSet->ToSetColor = 1;
2008
2009     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2010     Standard_Boolean     isOk   = Standard_False;
2011     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
2012     {
2013       aChangeSet->Color = aColor;
2014       aNames.Remove (aNames.Length());
2015       isOk = Standard_True;
2016     }
2017     else if (aNames.Length() >= 3)
2018     {
2019       const char* anArgVec[3] =
2020       {
2021         aNames.Value (aNames.Upper() - 2).ToCString(),
2022         aNames.Value (aNames.Upper() - 1).ToCString(),
2023         aNames.Value (aNames.Upper() - 0).ToCString(),
2024       };
2025
2026       Standard_Integer aNbParsed = ViewerTest::ParseColor (3, anArgVec, aChangeSet->Color);
2027       isOk = aNbParsed == 3;
2028       aNames.Remove (aNames.Length());
2029       aNames.Remove (aNames.Length());
2030       aNames.Remove (aNames.Length());
2031     }
2032     if (!isOk)
2033     {
2034       std::cout << "Error: not enough arguments!\n";
2035       return 1;
2036     }
2037   }
2038   else if (aCmdName == "vunsetcolor")
2039   {
2040     aChangeSet->ToSetColor = -1;
2041   }
2042   else if (aCmdName == "vsettransparency")
2043   {
2044     if (aNames.IsEmpty()
2045     || !aNames.Last().IsRealValue())
2046     {
2047       std::cout << "Error: not enough arguments!\n";
2048       return 1;
2049     }
2050     aChangeSet->ToSetTransparency = 1;
2051     aChangeSet->Transparency  = aNames.Last().RealValue();
2052     aNames.Remove (aNames.Length());
2053   }
2054   else if (aCmdName == "vunsettransparency")
2055   {
2056     aChangeSet->ToSetTransparency = -1;
2057   }
2058   else if (aCmdName == "vsetmaterial")
2059   {
2060     if (aNames.IsEmpty())
2061     {
2062       std::cout << "Error: not enough arguments!\n";
2063       return 1;
2064     }
2065     aChangeSet->ToSetMaterial = 1;
2066     aChangeSet->MatName  = aNames.Last();
2067     aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
2068     aNames.Remove (aNames.Length());
2069   }
2070   else if (aCmdName == "vunsetmaterial")
2071   {
2072     aChangeSet->ToSetMaterial = -1;
2073   }
2074   else if (aCmdName == "vsetinteriorstyle")
2075   {
2076     if (aNames.IsEmpty()
2077     || !aNames.Last().IsRealValue())
2078     {
2079       std::cout << "Error: not enough arguments!\n";
2080       return 1;
2081     }
2082     aChangeSet->ToSetInterior = 1;
2083     if (!parseInteriorStyle (aNames.Last(), aChangeSet->InteriorStyle))
2084     {
2085       std::cout << "Error: wrong syntax at " << aNames.Last() << "\n";
2086       return 1;
2087     }
2088     aNames.Remove (aNames.Length());
2089   }
2090   else if (aCmdName == "vsetedgetype")
2091   {
2092     aChangeSet->ToSetDrawEdges = 1;
2093     toParseAliasArgs = true;
2094   }
2095   else if (aCmdName == "vunsetedgetype")
2096   {
2097     aChangeSet->ToSetDrawEdges  = -1;
2098     aChangeSet->ToSetEdgeColor  = -1;
2099     aChangeSet->ToSetTypeOfEdge = -1;
2100     aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2101   }
2102   else if (anArgIter >= theArgNb)
2103   {
2104     std::cout << "Error: not enough arguments!\n";
2105     return 1;
2106   }
2107
2108   if (!aChangeSet->IsEmpty()
2109    && !toParseAliasArgs)
2110   {
2111     anArgIter = theArgNb;
2112   }
2113   for (; anArgIter < theArgNb; ++anArgIter)
2114   {
2115     TCollection_AsciiString anArg = theArgVec[anArgIter];
2116     anArg.LowerCase();
2117     if (anArg == "-setwidth"
2118      || anArg == "-width"
2119      || anArg == "-setlinewidth"
2120      || anArg == "-linewidth"
2121      || anArg == "-setedgewidth"
2122      || anArg == "-setedgeswidth"
2123      || anArg == "-edgewidth"
2124      || anArg == "-edgeswidth")
2125     {
2126       if (++anArgIter >= theArgNb)
2127       {
2128         std::cout << "Error: wrong syntax at " << anArg << "\n";
2129         return 1;
2130       }
2131       if (anArg == "-setedgewidth"
2132        || anArg == "-setedgeswidth"
2133        || anArg == "-edgewidth"
2134        || anArg == "-edgeswidth"
2135        || aCmdName == "vsetedgetype")
2136       {
2137         aChangeSet->ToSetEdgeWidth = 1;
2138         aChangeSet->EdgeWidth = Draw::Atof (theArgVec[anArgIter]);
2139       }
2140       else
2141       {
2142         aChangeSet->ToSetLineWidth = 1;
2143         aChangeSet->LineWidth = Draw::Atof (theArgVec[anArgIter]);
2144       }
2145     }
2146     else if (anArg == "-unsetwidth"
2147           || anArg == "-unsetlinewidth"
2148           || anArg == "-unsetedgewidth")
2149     {
2150       if (anArg == "-unsetedgewidth")
2151       {
2152         aChangeSet->ToSetEdgeWidth = -1;
2153         aChangeSet->EdgeWidth = 1.0;
2154       }
2155       else
2156       {
2157         aChangeSet->ToSetLineWidth = -1;
2158         aChangeSet->LineWidth = 1.0;
2159       }
2160     }
2161     else if (anArg == "-settransp"
2162           || anArg == "-settransparency"
2163           || anArg == "-transparency"
2164           || anArg == "-transp")
2165     {
2166       if (++anArgIter >= theArgNb)
2167       {
2168         std::cout << "Error: wrong syntax at " << anArg << "\n";
2169         return 1;
2170       }
2171       aChangeSet->ToSetTransparency = 1;
2172       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
2173       if (aChangeSet->Transparency >= 0.0
2174        && aChangeSet->Transparency <= Precision::Confusion())
2175       {
2176         aChangeSet->ToSetTransparency = -1;
2177         aChangeSet->Transparency = 0.0;
2178       }
2179     }
2180     else if (anArg == "-setalphamode"
2181           || anArg == "-alphamode")
2182     {
2183       if (++anArgIter >= theArgNb)
2184       {
2185         std::cout << "Error: wrong syntax at " << anArg << "\n";
2186         return 1;
2187       }
2188       aChangeSet->ToSetAlphaMode = 1;
2189       aChangeSet->AlphaCutoff = 0.5f;
2190       {
2191         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2192         aParam.LowerCase();
2193         if (aParam == "opaque")
2194         {
2195           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2196         }
2197         else if (aParam == "mask")
2198         {
2199           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2200         }
2201         else if (aParam == "blend")
2202         {
2203           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2204         }
2205         else if (aParam == "blendauto"
2206               || aParam == "auto")
2207         {
2208           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2209         }
2210         else
2211         {
2212           std::cout << "Error: wrong syntax at " << aParam << "\n";
2213           return 1;
2214         }
2215       }
2216
2217       if (anArgIter + 1 < theArgNb
2218        && theArgVec[anArgIter + 1][0] != '-')
2219       {
2220         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2221         if (aParam2.IsRealValue())
2222         {
2223           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2224           ++anArgIter;
2225         }
2226       }
2227     }
2228     else if (anArg == "-setvis"
2229           || anArg == "-setvisibility"
2230           || anArg == "-visibility")
2231     {
2232       if (++anArgIter >= theArgNb)
2233       {
2234         std::cout << "Error: wrong syntax at " << anArg << "\n";
2235         return 1;
2236       }
2237
2238       aChangeSet->ToSetVisibility = 1;
2239       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2240     }
2241     else if (anArg == "-setalpha"
2242           || anArg == "-alpha")
2243     {
2244       if (++anArgIter >= theArgNb)
2245       {
2246         std::cout << "Error: wrong syntax at " << anArg << "\n";
2247         return 1;
2248       }
2249       aChangeSet->ToSetTransparency = 1;
2250       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2251       if (aChangeSet->Transparency < 0.0
2252        || aChangeSet->Transparency > 1.0)
2253       {
2254         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
2255         return 1;
2256       }
2257       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2258       if (aChangeSet->Transparency >= 0.0
2259        && aChangeSet->Transparency <= Precision::Confusion())
2260       {
2261         aChangeSet->ToSetTransparency = -1;
2262         aChangeSet->Transparency = 0.0;
2263       }
2264     }
2265     else if (anArg == "-unsettransp"
2266           || anArg == "-unsettransparency"
2267           || anArg == "-unsetalpha"
2268           || anArg == "-opaque")
2269     {
2270       aChangeSet->ToSetTransparency = -1;
2271       aChangeSet->Transparency = 0.0;
2272     }
2273     else if (anArg == "-setcolor"
2274           || anArg == "-color")
2275     {
2276       Quantity_Color aColor;
2277       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2278                                                            theArgVec + anArgIter + 1,
2279                                                            aColor);
2280       if (aNbParsed == 0)
2281       {
2282         std::cout << "Syntax error at '" << anArg << "'\n";
2283         return 1;
2284       }
2285       anArgIter += aNbParsed;
2286       if (aCmdName == "vsetedgetype")
2287       {
2288         aChangeSet->ToSetEdgeColor = 1;
2289         aChangeSet->EdgeColor = Quantity_ColorRGBA (aColor);
2290       }
2291       else
2292       {
2293         aChangeSet->ToSetColor = 1;
2294         aChangeSet->Color = aColor;
2295       }
2296     }
2297     else if (anArg == "-setlinetype"
2298           || anArg == "-linetype"
2299           || anArg == "-setedgetype"
2300           || anArg == "-setedgestype"
2301           || anArg == "-edgetype"
2302           || anArg == "-edgestype"
2303           || anArg == "-type")
2304     {
2305       if (++anArgIter >= theArgNb)
2306       {
2307         std::cout << "Error: wrong syntax at " << anArg << "\n";
2308         return 1;
2309       }
2310       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
2311       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType))
2312       {
2313         std::cout << "Error: wrong syntax at " << anArg << "\n";
2314         return 1;
2315       }
2316       if (anArg == "-setedgetype"
2317        || anArg == "-setedgestype"
2318        || anArg == "-edgetype"
2319        || anArg == "-edgestype"
2320        || aCmdName == "vsetedgetype")
2321       {
2322         aChangeSet->TypeOfEdge = aLineType;
2323         aChangeSet->ToSetTypeOfEdge = 1;
2324       }
2325       else
2326       {
2327         aChangeSet->TypeOfLine = aLineType;
2328         aChangeSet->ToSetTypeOfLine = 1;
2329       }
2330     }
2331     else if (anArg == "-unsetlinetype"
2332           || anArg == "-unsetedgetype"
2333           || anArg == "-unsetedgestype")
2334     {
2335       if (anArg == "-unsetedgetype"
2336        || anArg == "-unsetedgestype")
2337       {
2338         aChangeSet->ToSetTypeOfEdge = -1;
2339       }
2340       else
2341       {
2342         aChangeSet->ToSetTypeOfLine = -1;
2343       }
2344     }
2345     else if (anArg == "-setmarkertype"
2346           || anArg == "-markertype"
2347           || anArg == "-setpointtype"
2348           || anArg == "-pointtype")
2349     {
2350       if (++anArgIter >= theArgNb)
2351       {
2352         std::cout << "Error: wrong syntax at " << anArg << "\n";
2353         return 1;
2354       }
2355       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2356       {
2357         std::cout << "Error: wrong syntax at " << anArg << "\n";
2358         return 1;
2359       }
2360
2361       aChangeSet->ToSetTypeOfMarker = 1;
2362     }
2363     else if (anArg == "-unsetmarkertype"
2364           || anArg == "-unsetpointtype")
2365     {
2366       aChangeSet->ToSetTypeOfMarker = -1;
2367     }
2368     else if (anArg == "-setmarkersize"
2369           || anArg == "-markersize"
2370           || anArg == "-setpointsize"
2371           || anArg == "-pointsize")
2372     {
2373       if (++anArgIter >= theArgNb)
2374       {
2375         std::cout << "Error: wrong syntax at " << anArg << "\n";
2376         return 1;
2377       }
2378       aChangeSet->ToSetMarkerSize = 1;
2379       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2380     }
2381     else if (anArg == "-unsetmarkersize"
2382           || anArg == "-unsetpointsize")
2383     {
2384       aChangeSet->ToSetMarkerSize = -1;
2385       aChangeSet->MarkerSize = 1.0;
2386     }
2387     else if (anArg == "-unsetcolor")
2388     {
2389       aChangeSet->ToSetColor = -1;
2390       aChangeSet->Color = DEFAULT_COLOR;
2391     }
2392     else if (anArg == "-setmat"
2393           || anArg == "-mat"
2394           || anArg == "-setmaterial"
2395           || anArg == "-material")
2396     {
2397       if (++anArgIter >= theArgNb)
2398       {
2399         std::cout << "Error: wrong syntax at " << anArg << "\n";
2400         return 1;
2401       }
2402       aChangeSet->ToSetMaterial = 1;
2403       aChangeSet->MatName  = theArgVec[anArgIter];
2404       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
2405     }
2406     else if (anArg == "-unsetmat"
2407           || anArg == "-unsetmaterial")
2408     {
2409       aChangeSet->ToSetMaterial = -1;
2410       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2411     }
2412     else if (anArg == "-subshape"
2413           || anArg == "-subshapes")
2414     {
2415       if (isDefaults)
2416       {
2417         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
2418         return 1;
2419       }
2420
2421       if (aNames.IsEmpty())
2422       {
2423         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
2424         return 1;
2425       }
2426
2427       aChanges.Append (ViewerTest_AspectsChangeSet());
2428       aChangeSet = &aChanges.ChangeLast();
2429
2430       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2431       {
2432         Standard_CString aSubShapeName = theArgVec[anArgIter];
2433         if (*aSubShapeName == '-')
2434         {
2435           --anArgIter;
2436           break;
2437         }
2438
2439         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2440         if (aSubShape.IsNull())
2441         {
2442           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2443           return 1;
2444         }
2445         aChangeSet->SubShapes.Append (aSubShape);
2446       }
2447
2448       if (aChangeSet->SubShapes.IsEmpty())
2449       {
2450         std::cerr << "Error: empty list is specified after -subshapes!\n";
2451         return 1;
2452       }
2453     }
2454     else if (anArg == "-setfreeboundary"
2455           || anArg == "-freeboundary"
2456           || anArg == "-setfb"
2457           || anArg == "-fb")
2458     {
2459       if (++anArgIter >= theArgNb)
2460       {
2461         std::cout << "Error: wrong syntax at " << anArg << "\n";
2462         return 1;
2463       }
2464       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2465       aValue.LowerCase();
2466       if (aValue == "on"
2467        || aValue == "1")
2468       {
2469         aChangeSet->ToSetShowFreeBoundary = 1;
2470       }
2471       else if (aValue == "off"
2472             || aValue == "0")
2473       {
2474         aChangeSet->ToSetShowFreeBoundary = -1;
2475       }
2476       else
2477       {
2478         std::cout << "Error: wrong syntax at " << anArg << "\n";
2479         return 1;
2480       }
2481     }
2482     else if (anArg == "-setfreeboundarywidth"
2483           || anArg == "-freeboundarywidth"
2484           || anArg == "-setfbwidth"
2485           || anArg == "-fbwidth")
2486     {
2487       if (++anArgIter >= theArgNb)
2488       {
2489         std::cout << "Error: wrong syntax at " << anArg << "\n";
2490         return 1;
2491       }
2492       aChangeSet->ToSetFreeBoundaryWidth = 1;
2493       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2494     }
2495     else if (anArg == "-unsetfreeboundarywidth"
2496           || anArg == "-unsetfbwidth")
2497     {
2498       aChangeSet->ToSetFreeBoundaryWidth = -1;
2499       aChangeSet->FreeBoundaryWidth = 1.0;
2500     }
2501     else if (anArg == "-setfreeboundarycolor"
2502           || anArg == "-freeboundarycolor"
2503           || anArg == "-setfbcolor"
2504           || anArg == "-fbcolor")
2505     {
2506       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2507                                                            theArgVec + anArgIter + 1,
2508                                                            aChangeSet->FreeBoundaryColor);
2509       if (aNbParsed == 0)
2510       {
2511         std::cout << "Syntax error at '" << anArg << "'\n";
2512         return 1;
2513       }
2514       anArgIter += aNbParsed;
2515       aChangeSet->ToSetFreeBoundaryColor = 1;
2516     }
2517     else if (anArg == "-unsetfreeboundarycolor"
2518           || anArg == "-unsetfbcolor")
2519     {
2520       aChangeSet->ToSetFreeBoundaryColor = -1;
2521       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2522     }
2523     else if (anArg == "-setisoontriangulation"
2524           || anArg == "-isoontriangulation"
2525           || anArg == "-setisoontriang"
2526           || anArg == "-isoontriang")
2527     {
2528       if (++anArgIter >= theArgNb)
2529       {
2530         std::cout << "Error: wrong syntax at " << anArg << "\n";
2531         return 1;
2532       }
2533       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2534       aValue.LowerCase();
2535       if (aValue == "on"
2536         || aValue == "1")
2537       {
2538         aChangeSet->ToEnableIsoOnTriangulation = 1;
2539       }
2540       else if (aValue == "off"
2541         || aValue == "0")
2542       {
2543         aChangeSet->ToEnableIsoOnTriangulation = 0;
2544       }
2545       else
2546       {
2547         std::cout << "Error: wrong syntax at " << anArg << "\n";
2548         return 1;
2549       }
2550     }
2551     else if (anArg == "-setmaxparamvalue"
2552           || anArg == "-maxparamvalue")
2553     {
2554       if (++anArgIter >= theArgNb)
2555       {
2556         std::cout << "Error: wrong syntax at " << anArg << "\n";
2557         return 1;
2558       }
2559       aChangeSet->ToSetMaxParamValue = 1;
2560       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
2561     }
2562     else if (anArg == "-setsensitivity"
2563           || anArg == "-sensitivity")
2564     {
2565       if (isDefaults)
2566       {
2567         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
2568         return 1;
2569       }
2570
2571       if (aNames.IsEmpty())
2572       {
2573         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
2574         return 1;
2575       }
2576
2577       if (anArgIter + 2 >= theArgNb)
2578       {
2579         std::cout << "Error: wrong syntax at " << anArg << "\n";
2580         return 1;
2581       }
2582       aChangeSet->ToSetSensitivity = 1;
2583       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
2584       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
2585     }
2586     else if (anArg == "-sethatch"
2587           || anArg == "-hatch")
2588     {
2589       if (isDefaults)
2590       {
2591         std::cout << "Error: wrong syntax. -setHatch can not be used together with -defaults call!\n";
2592         return 1;
2593       }
2594
2595       if (aNames.IsEmpty())
2596       {
2597         std::cout << "Error: object should be specified explicitly when -setHatch is used!\n";
2598         return 1;
2599       }
2600
2601       aChangeSet->ToSetHatch = 1;
2602       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
2603       if (anArgHatch.Length() <= 2)
2604       {
2605         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
2606         if (anIntStyle < 0
2607          || anIntStyle >= Aspect_HS_NB)
2608         {
2609           std::cout << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!\n";
2610           return 1;
2611         }
2612         aChangeSet->StdHatchStyle = anIntStyle;
2613       }
2614       else
2615       {
2616         aChangeSet->PathToHatchPattern = anArgHatch;
2617       }
2618     }
2619     else if (anArg == "-setshadingmodel"
2620           || anArg == "-setshading"
2621           || anArg == "-shadingmodel"
2622           || anArg == "-shading")
2623     {
2624       if (++anArgIter >= theArgNb)
2625       {
2626         std::cout << "Error: wrong syntax at " << anArg << "\n";
2627         return 1;
2628       }
2629       aChangeSet->ToSetShadingModel = 1;
2630       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
2631       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
2632       {
2633         std::cout << "Error: wrong syntax at " << anArg << "\n";
2634         return 1;
2635       }
2636     }
2637     else if (anArg == "-unsetshadingmodel")
2638     {
2639       aChangeSet->ToSetShadingModel = -1;
2640       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
2641     }
2642     else if (anArg == "-setinterior"
2643           || anArg == "-setinteriorstyle"
2644           || anArg == "-interior"
2645           || anArg == "-interiorstyle")
2646     {
2647       if (++anArgIter >= theArgNb)
2648       {
2649         std::cout << "Error: wrong syntax at " << anArg << "\n";
2650         return 1;
2651       }
2652       aChangeSet->ToSetInterior = 1;
2653       if (!parseInteriorStyle (theArgVec[anArgIter], aChangeSet->InteriorStyle))
2654       {
2655         std::cout << "Error: wrong syntax at " << anArg << "\n";
2656         return 1;
2657       }
2658     }
2659     else if (anArg == "-unsetinterior")
2660     {
2661       aChangeSet->ToSetInterior = -1;
2662       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
2663     }
2664     else if (anArg == "-setdrawedges"
2665           || anArg == "-setdrawedge"
2666           || anArg == "-drawedges"
2667           || anArg == "-drawedge"
2668           || anArg == "-edges")
2669     {
2670       bool toDrawEdges = true;
2671       if (anArgIter + 1 < theArgNb
2672        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toDrawEdges))
2673       {
2674         ++anArgIter;
2675       }
2676       aChangeSet->ToSetDrawEdges = toDrawEdges ? 1 : -1;
2677     }
2678     else if (anArg == "-setquadedges"
2679           || anArg == "-setquads"
2680           || anArg == "-quads"
2681           || anArg == "-skipfirstedge")
2682     {
2683       bool isQuadMode = true;
2684       if (anArgIter + 1 < theArgNb
2685        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isQuadMode))
2686       {
2687         ++anArgIter;
2688       }
2689       aChangeSet->ToSetQuadEdges = isQuadMode ? 1 : -1;
2690     }
2691     else if (anArg == "-setedgecolor"
2692           || anArg == "-setedgescolor"
2693           || anArg == "-edgecolor"
2694           || anArg == "-edgescolor")
2695     {
2696       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
2697                                                            theArgVec + anArgIter + 1,
2698                                                            aChangeSet->EdgeColor);
2699       if (aNbParsed == 0)
2700       {
2701         std::cout << "Syntax error at '" << anArg << "'\n";
2702         return 1;
2703       }
2704       anArgIter += aNbParsed;
2705       aChangeSet->ToSetEdgeColor = 1;
2706     }
2707     else if (anArg == "-unset")
2708     {
2709       aChangeSet->ToSetVisibility = 1;
2710       aChangeSet->Visibility = 1;
2711       aChangeSet->ToSetLineWidth = -1;
2712       aChangeSet->LineWidth = 1.0;
2713       aChangeSet->ToSetTypeOfLine = -1;
2714       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
2715       aChangeSet->ToSetTypeOfMarker = -1;
2716       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
2717       aChangeSet->ToSetMarkerSize = -1;
2718       aChangeSet->MarkerSize = 1.0;
2719       aChangeSet->ToSetTransparency = -1;
2720       aChangeSet->Transparency = 0.0;
2721       aChangeSet->ToSetAlphaMode = -1;
2722       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2723       aChangeSet->AlphaCutoff = 0.5f;
2724       aChangeSet->ToSetColor = -1;
2725       aChangeSet->Color = DEFAULT_COLOR;
2726       aChangeSet->ToSetMaterial = -1;
2727       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2728       aChangeSet->ToSetShowFreeBoundary = -1;
2729       aChangeSet->ToSetFreeBoundaryColor = -1;
2730       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2731       aChangeSet->ToSetFreeBoundaryWidth = -1;
2732       aChangeSet->FreeBoundaryWidth = 1.0;
2733       aChangeSet->ToSetHatch = -1;
2734       aChangeSet->StdHatchStyle = -1;
2735       aChangeSet->PathToHatchPattern.Clear();
2736       aChangeSet->ToSetShadingModel = -1;
2737       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
2738       aChangeSet->ToSetInterior = -1;
2739       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
2740       aChangeSet->ToSetDrawEdges = -1;
2741       aChangeSet->ToSetQuadEdges = -1;
2742       aChangeSet->ToSetEdgeColor = -1;
2743       aChangeSet->EdgeColor = Quantity_ColorRGBA (DEFAULT_COLOR);
2744       aChangeSet->ToSetEdgeWidth = -1;
2745       aChangeSet->EdgeWidth = 1.0;
2746       aChangeSet->ToSetTypeOfEdge = -1;
2747       aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2748     }
2749     else
2750     {
2751       std::cout << "Error: wrong syntax at " << anArg << "\n";
2752       return 1;
2753     }
2754   }
2755
2756   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2757        aChangesIter.More(); aChangesIter.Next())
2758   {
2759     if (!aChangesIter.Value().Validate())
2760     {
2761       return 1;
2762     }
2763   }
2764
2765   // special case for -defaults parameter.
2766   // all changed values will be set to DefaultDrawer.
2767   if (isDefaults)
2768   {
2769     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
2770     aChangeSet->Apply (aDrawer);
2771     if (aChangeSet->ToSetLineWidth != 0)
2772     {
2773       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
2774       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
2775       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
2776       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
2777     }
2778     if (aChangeSet->ToSetColor != 0)
2779     {
2780       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
2781       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
2782       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
2783       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
2784       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
2785       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
2786     }
2787     if (aChangeSet->ToSetTransparency != 0)
2788     {
2789       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
2790     }
2791     if (aChangeSet->ToSetMaterial != 0)
2792     {
2793       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
2794     }
2795     if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2796     {
2797       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
2798     }
2799
2800     // redisplay all objects in context
2801     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2802     {
2803       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
2804       if (!aPrs.IsNull())
2805       {
2806         aCtx->Redisplay (aPrs, Standard_False);
2807       }
2808     }
2809     return 0;
2810   }
2811
2812   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2813   {
2814     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
2815     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
2816     if (aPrs.IsNull())
2817     {
2818       return 1;
2819     }
2820
2821     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
2822     Handle(AIS_ColoredShape) aColoredPrs;
2823     Standard_Boolean toDisplay = Standard_False;
2824     Standard_Boolean toRedisplay = Standard_False;
2825     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
2826     {
2827       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
2828       if (aShapePrs.IsNull())
2829       {
2830         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
2831         return 1;
2832       }
2833       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
2834       if (aColoredPrs.IsNull())
2835       {
2836         aColoredPrs = new AIS_ColoredShape (aShapePrs);
2837         if (aShapePrs->HasDisplayMode())
2838         {
2839           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
2840         }
2841         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
2842         aCtx->Remove (aShapePrs, Standard_False);
2843         GetMapOfAIS().UnBind2 (aName);
2844         GetMapOfAIS().Bind (aColoredPrs, aName);
2845         toDisplay = Standard_True;
2846         aShapePrs = aColoredPrs;
2847         aPrs      = aColoredPrs;
2848       }
2849     }
2850
2851     if (!aPrs.IsNull())
2852     {
2853       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2854       aChangeSet = &aChangesIter.ChangeValue();
2855       if (aChangeSet->ToSetVisibility == 1)
2856       {
2857         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
2858         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
2859       }
2860       else if (aChangeSet->ToSetMaterial == 1)
2861       {
2862         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
2863       }
2864       else if (aChangeSet->ToSetMaterial == -1)
2865       {
2866         aCtx->UnsetMaterial (aPrs, Standard_False);
2867       }
2868       if (aChangeSet->ToSetColor == 1)
2869       {
2870         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
2871       }
2872       else if (aChangeSet->ToSetColor == -1)
2873       {
2874         aCtx->UnsetColor (aPrs, Standard_False);
2875       }
2876       if (aChangeSet->ToSetTransparency == 1)
2877       {
2878         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
2879       }
2880       else if (aChangeSet->ToSetTransparency == -1)
2881       {
2882         aCtx->UnsetTransparency (aPrs, Standard_False);
2883       }
2884       if (aChangeSet->ToSetLineWidth == 1)
2885       {
2886         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
2887       }
2888       else if (aChangeSet->ToSetLineWidth == -1)
2889       {
2890         aCtx->UnsetWidth (aPrs, Standard_False);
2891       }
2892       else if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2893       {
2894         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
2895         toRedisplay = Standard_True;
2896       }
2897       else if (aChangeSet->ToSetSensitivity != 0)
2898       {
2899         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2900       }
2901       if (!aDrawer.IsNull())
2902       {
2903         toRedisplay = aChangeSet->Apply (aDrawer) || toRedisplay;
2904       }
2905
2906       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
2907       {
2908         aChangeSet = &aChangesIter.ChangeValue();
2909         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
2910              aSubShapeIter.More(); aSubShapeIter.Next())
2911         {
2912           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
2913           if (!aChangeSet->IsEmpty())
2914           {
2915             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2916             aChangeSet->Apply (aCurColDrawer);
2917           }
2918           if (aChangeSet->ToSetVisibility == 1)
2919           {
2920             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2921             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
2922           }
2923           if (aChangeSet->ToSetColor == 1)
2924           {
2925             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
2926           }
2927           if (aChangeSet->ToSetTransparency == 1)
2928           {
2929             aColoredPrs->SetCustomTransparency (aSubShape, aChangeSet->Transparency);
2930           }
2931           if (aChangeSet->ToSetLineWidth == 1)
2932           {
2933             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
2934           }
2935           if (aChangeSet->ToSetColor     == -1
2936            || aChangeSet->ToSetLineWidth == -1)
2937           {
2938             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
2939           }
2940           if (aChangeSet->ToSetSensitivity != 0)
2941           {
2942             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2943           }
2944         }
2945       }
2946       if (toDisplay)
2947       {
2948         aCtx->Display (aPrs, Standard_False);
2949       }
2950       if (toRedisplay)
2951       {
2952         aCtx->Redisplay (aPrs, Standard_False);
2953       }
2954       else if (!aColoredPrs.IsNull())
2955       {
2956         aCtx->Redisplay (aColoredPrs, Standard_False);
2957       }
2958       else
2959       {
2960         aPrs->SynchronizeAspects();
2961       }
2962     }
2963   }
2964   return 0;
2965 }
2966
2967 //==============================================================================
2968 //function : VDonly2
2969 //author   : ege
2970 //purpose  : Display only a selected or named  object
2971 //           if there is no selected or named object s, nothing is done
2972 //==============================================================================
2973 static int VDonly2 (Draw_Interpretor& ,
2974                     Standard_Integer  theArgNb,
2975                     const char**      theArgVec)
2976 {
2977   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2978   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2979   if (aCtx.IsNull())
2980   {
2981     std::cerr << "Error: no active view!\n";
2982     return 1;
2983   }
2984
2985   Standard_Integer anArgIter = 1;
2986   for (; anArgIter < theArgNb; ++anArgIter)
2987   {
2988     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
2989     {
2990       break;
2991     }
2992   }
2993
2994   NCollection_Map<Handle(Standard_Transient)> aDispSet;
2995   if (anArgIter >= theArgNb)
2996   {
2997     // display only selected objects
2998     if (aCtx->NbSelected() < 1)
2999     {
3000       return 0;
3001     }
3002
3003     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3004     {
3005       aDispSet.Add (aCtx->SelectedInteractive());
3006     }
3007   }
3008   else
3009   {
3010     // display only specified objects
3011     for (; anArgIter < theArgNb; ++anArgIter)
3012     {
3013       TCollection_AsciiString aName = theArgVec[anArgIter];
3014       Handle(AIS_InteractiveObject) aShape;
3015       if (GetMapOfAIS().Find2 (aName, aShape)
3016       && !aShape.IsNull())
3017       {
3018         aCtx->Display (aShape, Standard_False);
3019         aDispSet.Add (aShape);
3020       }
3021     }
3022   }
3023
3024   // weed out other objects
3025   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
3026   {
3027     if (aDispSet.Contains (anIter.Key1()))
3028     {
3029       continue;
3030     }
3031
3032     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
3033     {
3034       aCtx->Erase (aShape, Standard_False);
3035     }
3036   }
3037   return 0;
3038 }
3039
3040 //==============================================================================
3041 //function : VRemove
3042 //purpose  : Removes selected or named objects.
3043 //           If there is no selected or named objects,
3044 //           all objects in the viewer can be removed with argument -all.
3045 //           If -context is in arguments, the object is not deleted from the map of
3046 //           objects (deleted only from the current context).
3047 //==============================================================================
3048 int VRemove (Draw_Interpretor& theDI,
3049              Standard_Integer  theArgNb,
3050              const char**      theArgVec)
3051 {
3052   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3053   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3054   if (aCtx.IsNull())
3055   {
3056     std::cerr << "Error: no active view!\n";
3057     return 1;
3058   }
3059
3060   Standard_Boolean isContextOnly = Standard_False;
3061   Standard_Boolean toRemoveAll   = Standard_False;
3062   Standard_Boolean toPrintInfo   = Standard_True;
3063
3064   Standard_Integer anArgIter = 1;
3065   for (; anArgIter < theArgNb; ++anArgIter)
3066   {
3067     TCollection_AsciiString anArg = theArgVec[anArgIter];
3068     anArg.LowerCase();
3069     if (anArg == "-context")
3070     {
3071       isContextOnly = Standard_True;
3072     }
3073     else if (anArg == "-all")
3074     {
3075       toRemoveAll = Standard_True;
3076     }
3077     else if (anArg == "-noinfo")
3078     {
3079       toPrintInfo = Standard_False;
3080     }
3081     else if (anUpdateTool.parseRedrawMode (anArg))
3082     {
3083       continue;
3084     }
3085     else
3086     {
3087       break;
3088     }
3089   }
3090   if (toRemoveAll
3091    && anArgIter < theArgNb)
3092   {
3093     std::cerr << "Error: wrong syntax!\n";
3094     return 1;
3095   }
3096
3097   NCollection_List<TCollection_AsciiString> anIONameList;
3098   if (toRemoveAll)
3099   {
3100     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3101          anIter.More(); anIter.Next())
3102     {
3103       anIONameList.Append (anIter.Key2());
3104     }
3105   }
3106   else if (anArgIter < theArgNb) // removed objects names are in argument list
3107   {
3108     for (; anArgIter < theArgNb; ++anArgIter)
3109     {
3110       TCollection_AsciiString aName = theArgVec[anArgIter];
3111       Handle(AIS_InteractiveObject) anIO;
3112       if (!GetMapOfAIS().Find2 (aName, anIO))
3113       {
3114         theDI << aName << " was not bound to some object.\n";
3115         continue;
3116       }
3117
3118       if (anIO->GetContext() != aCtx)
3119       {
3120         theDI << aName << " was not displayed in current context.\n";
3121         theDI << "Please activate view with this object displayed and try again.\n";
3122         continue;
3123       }
3124
3125       anIONameList.Append (aName);
3126       continue;
3127     }
3128   }
3129   else if (aCtx->NbSelected() > 0)
3130   {
3131     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3132          anIter.More(); anIter.Next())
3133     {
3134       if (!aCtx->IsSelected (anIter.Key1()))
3135       {
3136         continue;
3137       }
3138
3139       anIONameList.Append (anIter.Key2());
3140       continue;
3141     }
3142   }
3143
3144   // Unbind all removed objects from the map of displayed IO.
3145   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
3146        anIter.More(); anIter.Next())
3147   {
3148     const Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (anIter.Value());
3149     aCtx->Remove (anIO, Standard_False);
3150     if (toPrintInfo)
3151     {
3152       theDI << anIter.Value() << " was removed\n";
3153     }
3154     if (!isContextOnly)
3155     {
3156       GetMapOfAIS().UnBind2 (anIter.Value());
3157     }
3158   }
3159   return 0;
3160 }
3161
3162 //==============================================================================
3163 //function : VErase
3164 //purpose  : Erase some selected or named objects
3165 //           if there is no selected or named objects, the whole viewer is erased
3166 //==============================================================================
3167 int VErase (Draw_Interpretor& theDI,
3168             Standard_Integer  theArgNb,
3169             const char**      theArgVec)
3170 {
3171   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
3172   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
3173   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
3174   if (aCtx.IsNull())
3175   {
3176     std::cerr << "Error: no active view!\n";
3177     return 1;
3178   }
3179
3180   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
3181
3182   Standard_Integer anArgIter = 1;
3183   Standard_Boolean toEraseInView = Standard_False;
3184   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
3185   for (; anArgIter < theArgNb; ++anArgIter)
3186   {
3187     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3188     anArgCase.LowerCase();
3189     if (anUpdateTool.parseRedrawMode (anArgCase))
3190     {
3191       continue;
3192     }
3193     else if (anArgCase == "-view"
3194           || anArgCase == "-inview")
3195     {
3196       toEraseInView = Standard_True;
3197     }
3198     else
3199     {
3200       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
3201     }
3202   }
3203
3204   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
3205   {
3206     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
3207     return 1;
3208   }
3209
3210   if (!aNamesOfEraseIO.IsEmpty())
3211   {
3212     // Erase named objects
3213     for (Standard_Integer anIter = 1; anIter <= aNamesOfEraseIO.Length(); ++anIter)
3214     {
3215       TCollection_AsciiString aName = aNamesOfEraseIO.Value (anIter);
3216       Handle(AIS_InteractiveObject) anIO;
3217       if (!GetMapOfAIS().Find2 (aName, anIO))
3218       {
3219         continue;
3220       }
3221
3222       theDI << aName << " ";
3223       if (!anIO.IsNull())
3224       {
3225         if (toEraseInView)
3226         {
3227           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3228         }
3229         else
3230         {
3231           aCtx->Erase (anIO, Standard_False);
3232         }
3233       }
3234     }
3235   }
3236   else if (!toEraseAll && aCtx->NbSelected() > 0)
3237   {
3238     // Erase selected objects
3239     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3240          anIter.More(); anIter.Next())
3241     {
3242       const Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3243       if (!anIO.IsNull()
3244        && aCtx->IsSelected (anIO))
3245       {
3246         theDI << anIter.Key2() << " ";
3247         if (toEraseInView)
3248         {
3249           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3250         }
3251       }
3252     }
3253
3254     if (!toEraseInView)
3255     {
3256       aCtx->EraseSelected (Standard_False);
3257     }
3258   }
3259   else
3260   {
3261     // Erase all objects
3262     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3263          anIter.More(); anIter.Next())
3264     {
3265       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3266       if (!anIO.IsNull())
3267       {
3268         if (toEraseInView)
3269         {
3270           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3271         }
3272         else
3273         {
3274           aCtx->Erase (anIO, Standard_False);
3275         }
3276       }
3277     }
3278   }
3279
3280   return 0;
3281 }
3282
3283 //==============================================================================
3284 //function : VDisplayAll
3285 //purpose  : Display all the objects of the Map
3286 //==============================================================================
3287 static int VDisplayAll (Draw_Interpretor& ,
3288                         Standard_Integer  theArgNb,
3289                         const char**      theArgVec)
3290
3291 {
3292   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3293   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3294   if (aCtx.IsNull())
3295   {
3296     std::cerr << "Error: no active view!\n";
3297     return 1;
3298   }
3299
3300   Standard_Integer anArgIter = 1;
3301   for (; anArgIter < theArgNb; ++anArgIter)
3302   {
3303     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3304     anArgCase.LowerCase();
3305     if (anUpdateTool.parseRedrawMode (anArgCase))
3306     {
3307       continue;
3308     }
3309     else
3310     {
3311       break;
3312     }
3313   }
3314   if (anArgIter < theArgNb)
3315   {
3316     std::cout << theArgVec[0] << "Error: wrong syntax\n";
3317     return 1;
3318   }
3319
3320   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3321        anIter.More(); anIter.Next())
3322   {
3323     aCtx->Erase (anIter.Key1(), Standard_False);
3324   }
3325
3326   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3327        anIter.More(); anIter.Next())
3328   {
3329     aCtx->Display (anIter.Key1(), Standard_False);
3330   }
3331   return 0;
3332 }
3333
3334 //! Auxiliary method to check if presentation exists
3335 inline Standard_Integer checkMode (const Handle(AIS_InteractiveContext)& theCtx,
3336                                    const Handle(AIS_InteractiveObject)&  theIO,
3337                                    const Standard_Integer                theMode)
3338 {
3339   if (theIO.IsNull() || theCtx.IsNull())
3340   {
3341     return -1;
3342   }
3343
3344   if (theMode != -1)
3345   {
3346     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
3347     {
3348       return theMode;
3349     }
3350   }
3351   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
3352   {
3353     return theIO->DisplayMode();
3354   }
3355   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
3356   {
3357     return theCtx->DisplayMode();
3358   }
3359
3360   return -1;
3361 }
3362
3363 enum ViewerTest_BndAction
3364 {
3365   BndAction_Hide,
3366   BndAction_Show,
3367   BndAction_Print
3368 };
3369
3370 //! Auxiliary method to print bounding box of presentation
3371 inline void bndPresentation (Draw_Interpretor&                         theDI,
3372                              const Handle(PrsMgr_PresentationManager)& theMgr,
3373                              const Handle(AIS_InteractiveObject)&      theObj,
3374                              const Standard_Integer                    theDispMode,
3375                              const TCollection_AsciiString&            theName,
3376                              const ViewerTest_BndAction                theAction,
3377                              const Handle(Prs3d_Drawer)&               theStyle)
3378 {
3379   switch (theAction)
3380   {
3381     case BndAction_Hide:
3382     {
3383       theMgr->Unhighlight (theObj);
3384       break;
3385     }
3386     case BndAction_Show:
3387     {
3388       theMgr->Color (theObj, theStyle, theDispMode);
3389       break;
3390     }
3391     case BndAction_Print:
3392     {
3393       Bnd_Box aBox;
3394       for (PrsMgr_Presentations::Iterator aPrsIter (theObj->Presentations()); aPrsIter.More(); aPrsIter.Next())
3395       {
3396         if (aPrsIter.Value().Mode() != theDispMode)
3397           continue;
3398
3399         aBox = aPrsIter.Value().Presentation()->Presentation()->MinMaxValues();
3400       }
3401       gp_Pnt aMin = aBox.CornerMin();
3402       gp_Pnt aMax = aBox.CornerMax();
3403       theDI << theName  << "\n"
3404             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
3405             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
3406       break;
3407     }
3408   }
3409 }
3410
3411 //==============================================================================
3412 //function : VBounding
3413 //purpose  :
3414 //==============================================================================
3415 int VBounding (Draw_Interpretor& theDI,
3416                Standard_Integer  theArgNb,
3417                const char**      theArgVec)
3418 {
3419   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3420   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3421   if (aCtx.IsNull())
3422   {
3423     std::cout << "Error: no active view!\n";
3424     return 1;
3425   }
3426
3427   ViewerTest_BndAction anAction = BndAction_Show;
3428   Standard_Integer     aMode    = -1;
3429
3430   Handle(Prs3d_Drawer) aStyle;
3431
3432   Standard_Integer anArgIter = 1;
3433   for (; anArgIter < theArgNb; ++anArgIter)
3434   {
3435     TCollection_AsciiString anArg (theArgVec[anArgIter]);
3436     anArg.LowerCase();
3437     if (anArg == "-print")
3438     {
3439       anAction = BndAction_Print;
3440     }
3441     else if (anArg == "-show")
3442     {
3443       anAction = BndAction_Show;
3444     }
3445     else if (anArg == "-hide")
3446     {
3447       anAction = BndAction_Hide;
3448     }
3449     else if (anArg == "-mode")
3450     {
3451       if (++anArgIter >= theArgNb)
3452       {
3453         std::cout << "Error: wrong syntax at " << anArg << "\n";
3454         return 1;
3455       }
3456       aMode = Draw::Atoi (theArgVec[anArgIter]);
3457     }
3458     else if (!anUpdateTool.parseRedrawMode (anArg))
3459     {
3460       break;
3461     }
3462   }
3463
3464   if (anAction == BndAction_Show)
3465   {
3466     aStyle = new Prs3d_Drawer();
3467     aStyle->SetMethod (Aspect_TOHM_BOUNDBOX);
3468     aStyle->SetColor  (Quantity_NOC_GRAY99);
3469   }
3470
3471   Standard_Integer aHighlightedMode = -1;
3472   if (anArgIter < theArgNb)
3473   {
3474     // has a list of names
3475     for (; anArgIter < theArgNb; ++anArgIter)
3476     {
3477       TCollection_AsciiString aName = theArgVec[anArgIter];
3478       Handle(AIS_InteractiveObject) anIO;
3479       if (!GetMapOfAIS().Find2 (aName, anIO))
3480       {
3481         std::cout << "Error: presentation " << aName << " does not exist\n";
3482         return 1;
3483       }
3484
3485       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3486       if (aHighlightedMode == -1)
3487       {
3488         std::cout << "Error: object " << aName << " has no presentation with mode " << aMode << std::endl;
3489         return 1;
3490       }
3491       bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, aName, anAction, aStyle);
3492     }
3493   }
3494   else if (aCtx->NbSelected() > 0)
3495   {
3496     // remove all currently selected objects
3497     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3498     {
3499       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
3500       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3501       if (aHighlightedMode != -1)
3502       {
3503         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode,
3504           GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction, aStyle);
3505       }
3506     }
3507   }
3508   else
3509   {
3510     // all objects
3511     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3512          anIter.More(); anIter.Next())
3513     {
3514       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3515       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3516       if (aHighlightedMode != -1)
3517       {
3518         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, anIter.Key2(), anAction, aStyle);
3519       }
3520     }
3521   }
3522   return 0;
3523 }
3524
3525 //==============================================================================
3526 //function : VTexture
3527 //purpose  :
3528 //==============================================================================
3529 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
3530 {
3531   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3532   if (aCtx.IsNull())
3533   {
3534     std::cout << "Error: no active view!\n";
3535     return 1;
3536   }
3537
3538   int  toModulate     = -1;
3539   bool toSetFilter    = false;
3540   bool toSetAniso     = false;
3541   bool toSetTrsfAngle = false;
3542   bool toSetTrsfTrans = false;
3543   bool toSetTrsfScale = false;
3544   Standard_ShortReal aTrsfRotAngle = 0.0f;
3545   Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f);
3546   Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f);
3547   Graphic3d_TypeOfTextureFilter      aFilter       = Graphic3d_TOTF_NEAREST;
3548   Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
3549
3550   Handle(AIS_InteractiveObject) aTexturedIO;
3551   Handle(AIS_Shape) aTexturedShape;
3552   Handle(Graphic3d_TextureSet) aTextureSetOld;
3553   NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
3554   bool toSetGenRepeat = false;
3555   bool toSetGenScale  = false;
3556   bool toSetGenOrigin = false;
3557   bool toSetImage     = false;
3558   bool toComputeUV    = false;
3559
3560   const TCollection_AsciiString aCommandName (theArgVec[0]);
3561   bool toSetDefaults = aCommandName == "vtexdefault";
3562
3563   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3564   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
3565   {
3566     const TCollection_AsciiString aName     = theArgVec[anArgIter];
3567     TCollection_AsciiString       aNameCase = aName;
3568     aNameCase.LowerCase();
3569     if (anUpdateTool.parseRedrawMode (aName))
3570     {
3571       continue;
3572     }
3573     else if (aTexturedIO.IsNull())
3574     {
3575       const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
3576       if (aMapOfIO.IsBound2 (aName))
3577       {
3578         aTexturedIO = aMapOfIO.Find2 (aName);
3579         aTexturedShape = Handle(AIS_Shape)::DownCast (aTexturedIO);
3580       }
3581       if (aTexturedIO.IsNull())
3582       {
3583         std::cout << "Syntax error: shape " << aName << " does not exists in the viewer.\n";
3584         return 1;
3585       }
3586
3587       if (aTexturedIO->Attributes()->HasOwnShadingAspect())
3588       {
3589         aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
3590       }
3591     }
3592     else if (!aTexturedShape.IsNull()
3593           && (aNameCase == "-scale"
3594            || aNameCase == "-setscale"
3595            || aCommandName == "vtexscale"))
3596     {
3597       if (aCommandName != "vtexscale")
3598       {
3599         ++anArgIter;
3600       }
3601       if (anArgIter < theArgsNb)
3602       {
3603         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3604         TCollection_AsciiString aValUCase = aValU;
3605         aValUCase.LowerCase();
3606         toSetGenScale = true;
3607         if (aValUCase == "off")
3608         {
3609           aTexturedShape->SetTextureScaleUV (gp_Pnt2d (1.0, 1.0));
3610           continue;
3611         }
3612         else if (anArgIter + 1 < theArgsNb)
3613         {
3614           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3615           if (aValU.IsRealValue()
3616            && aValV.IsRealValue())
3617           {
3618             aTexturedShape->SetTextureScaleUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3619             ++anArgIter;
3620             continue;
3621           }
3622         }
3623       }
3624       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3625       return 1;
3626     }
3627     else if (!aTexturedShape.IsNull()
3628           && (aNameCase == "-origin"
3629            || aNameCase == "-setorigin"
3630            || aCommandName == "vtexorigin"))
3631     {
3632       if (aCommandName != "vtexorigin")
3633       {
3634         ++anArgIter;
3635       }
3636       if (anArgIter < theArgsNb)
3637       {
3638         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3639         TCollection_AsciiString aValUCase = aValU;
3640         aValUCase.LowerCase();
3641         toSetGenOrigin = true;
3642         if (aValUCase == "off")
3643         {
3644           aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
3645           continue;
3646         }
3647         else if (anArgIter + 1 < theArgsNb)
3648         {
3649           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3650           if (aValU.IsRealValue()
3651            && aValV.IsRealValue())
3652           {
3653             aTexturedShape->SetTextureOriginUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3654             ++anArgIter;
3655             continue;
3656           }
3657         }
3658       }
3659       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3660       return 1;
3661     }
3662     else if (!aTexturedShape.IsNull()
3663           && (aNameCase == "-repeat"
3664            || aNameCase == "-setrepeat"
3665            || aCommandName == "vtexrepeat"))
3666     {
3667       if (aCommandName != "vtexrepeat")
3668       {
3669         ++anArgIter;
3670       }
3671       if (anArgIter < theArgsNb)
3672       {
3673         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3674         TCollection_AsciiString aValUCase = aValU;
3675         aValUCase.LowerCase();
3676         toSetGenRepeat = true;
3677         if (aValUCase == "off")
3678         {
3679           aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
3680           continue;
3681         }
3682         else if (anArgIter + 1 < theArgsNb)
3683         {
3684           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3685           if (aValU.IsRealValue()
3686            && aValV.IsRealValue())
3687           {
3688             aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3689             ++anArgIter;
3690             continue;
3691           }
3692         }
3693       }
3694       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3695       return 1;
3696     }
3697     else if (aNameCase == "-modulate")
3698     {
3699       bool toModulateBool = true;
3700       if (anArgIter + 1 < theArgsNb
3701        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toModulateBool))
3702       {
3703         ++anArgIter;
3704       }
3705       toModulate = toModulateBool ? 1 : 0;
3706     }
3707     else if ((aNameCase == "-setfilter"
3708            || aNameCase == "-filter")
3709            && anArgIter + 1 < theArgsNb)
3710     {
3711       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
3712       aValue.LowerCase();
3713       ++anArgIter;
3714       toSetFilter = true;
3715       if (aValue == "nearest")
3716       {
3717         aFilter = Graphic3d_TOTF_NEAREST;
3718       }
3719       else if (aValue == "bilinear")
3720       {
3721         aFilter = Graphic3d_TOTF_BILINEAR;
3722       }
3723       else if (aValue == "trilinear")
3724       {
3725         aFilter = Graphic3d_TOTF_TRILINEAR;
3726       }
3727       else
3728       {
3729         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
3730         return 1;
3731       }
3732     }
3733     else if ((aNameCase == "-setaniso"
3734            || aNameCase == "-setanisofilter"
3735            || aNameCase == "-aniso"
3736            || aNameCase == "-anisofilter")
3737            && anArgIter + 1 < theArgsNb)
3738     {
3739       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
3740       aValue.LowerCase();
3741       ++anArgIter;
3742       toSetAniso = true;
3743       if (aValue == "off")
3744       {
3745         anAnisoFilter = Graphic3d_LOTA_OFF;
3746       }
3747       else if (aValue == "fast")
3748       {
3749         anAnisoFilter = Graphic3d_LOTA_FAST;
3750       }
3751       else if (aValue == "middle")
3752       {
3753         anAnisoFilter = Graphic3d_LOTA_MIDDLE;
3754       }
3755       else if (aValue == "quality"
3756             || aValue == "high")
3757       {
3758         anAnisoFilter =  Graphic3d_LOTA_QUALITY;
3759       }
3760       else
3761       {
3762         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
3763         return 1;
3764       }
3765     }
3766     else if ((aNameCase == "-rotateangle"
3767            || aNameCase == "-rotangle"
3768            || aNameCase == "-rotate"
3769            || aNameCase == "-angle"
3770            || aNameCase == "-trsfangle")
3771            && anArgIter + 1 < theArgsNb)
3772     {
3773       aTrsfRotAngle  = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
3774       toSetTrsfAngle = true;
3775       ++anArgIter;
3776     }
3777     else if ((aNameCase == "-trsftrans"
3778            || aNameCase == "-trsftranslate"
3779            || aNameCase == "-translate"
3780            || aNameCase == "-translation")
3781            && anArgIter + 2 < theArgsNb)
3782     {
3783       aTrsfTrans.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
3784       aTrsfTrans.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
3785       toSetTrsfTrans = true;
3786       anArgIter += 2;
3787     }
3788     else if ((aNameCase == "-trsfscale")
3789            && anArgIter + 2 < theArgsNb)
3790     {
3791       aTrsfScale.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
3792       aTrsfScale.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
3793       toSetTrsfScale = true;
3794       anArgIter += 2;
3795     }
3796     else if (aNameCase == "-default"
3797           || aNameCase == "-defaults")
3798     {
3799       toSetDefaults = true;
3800     }
3801     else if (aCommandName == "vtexture"
3802           && (aTextureVecNew.IsEmpty()
3803            || aNameCase.StartsWith ("-tex")))
3804     {
3805       Standard_Integer aTexIndex = 0;
3806       TCollection_AsciiString aTexName = aName;
3807       if (aNameCase.StartsWith ("-tex"))
3808       {
3809         if (anArgIter + 1 >= theArgsNb
3810          || aNameCase.Length() < 5)
3811         {
3812           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
3813           return 1;
3814         }
3815
3816         TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
3817         if (!aTexIndexStr.IsIntegerValue())
3818         {
3819           std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
3820           return 1;
3821         }
3822
3823         aTexIndex = aTexIndexStr.IntegerValue();
3824         aTexName  = theArgVec[anArgIter + 1];
3825         ++anArgIter;
3826       }
3827       if (aTexIndex >= Graphic3d_TextureUnit_NB
3828        || aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
3829       {
3830         std::cout << "Error: too many textures specified\n";
3831         return 1;
3832       }
3833
3834       toSetImage = true;
3835       if (aTexName.IsIntegerValue())
3836       {
3837         const Standard_Integer aValue = aTexName.IntegerValue();
3838         if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
3839         {
3840           std::cout << "Syntax error: texture with ID " << aValue << " is undefined!\n";
3841           return 1;
3842         }
3843         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
3844       }
3845       else if (aTexName == "?")
3846       {
3847         const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
3848
3849         theDi << "\n Files in current directory : \n\n";
3850         theDi.Eval ("glob -nocomplain *");
3851
3852         TCollection_AsciiString aCmnd ("glob -nocomplain ");
3853         aCmnd += aTextureFolder;
3854         aCmnd += "/* ";
3855
3856         theDi << "Files in " << aTextureFolder << " : \n\n";
3857         theDi.Eval (aCmnd.ToCString());
3858         return 0;
3859       }
3860       else if (aTexName != "off")
3861       {
3862         if (!OSD_File (aTexName).Exists())
3863         {
3864           std::cout << "Syntax error: non-existing image file has been specified '" << aTexName << "'.\n";
3865           return 1;
3866         }
3867         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
3868       }
3869       else
3870       {
3871         aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
3872       }
3873
3874       if (aTextureVecNew.Value (aTexIndex))
3875       {
3876         aTextureVecNew.ChangeValue(aTexIndex)->GetParams()->SetTextureUnit((Graphic3d_TextureUnit)aTexIndex);
3877       }
3878     }
3879     else
3880     {
3881       std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
3882       return 1;
3883     }
3884   }
3885
3886   if (toSetImage)
3887   {
3888     // check if new image set is equal to already set one
3889     Standard_Integer aNbChanged = 0;
3890     Handle(Graphic3d_TextureSet) aTextureSetNew;
3891     if (!aTextureVecNew.IsEmpty())
3892     {
3893       aNbChanged = aTextureVecNew.Size();
3894       aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
3895       for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
3896       {
3897         Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
3898         Handle(Graphic3d_TextureRoot) aTextureOld;
3899         if (!aTextureSetOld.IsNull()
3900           && aTexIter < aTextureSetOld->Size())
3901         {
3902           aTextureOld = aTextureSetOld->Value (aTexIter);
3903         }
3904
3905         if (!aTextureOld.IsNull()
3906          && !aTextureNew.IsNull())
3907         {
3908           *aTextureNew->GetParams() = *aTextureOld->GetParams();
3909           if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
3910           {
3911             TCollection_AsciiString aFilePathOld, aFilePathNew;
3912             aTextureOld->Path().SystemName (aFilePathOld);
3913             aTextureNew->Path().SystemName (aFilePathNew);
3914             if (aTextureNew->Name() == anOldManualTex->Name()
3915              && aFilePathOld == aFilePathNew
3916              && (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
3917             {
3918               --aNbChanged;
3919               aTextureNew = anOldManualTex;
3920             }
3921           }
3922         }
3923         aTextureSetNew->SetValue (aTexIter, aTextureNew);
3924       }
3925     }
3926     if (aNbChanged == 0
3927      && ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
3928       || (aTextureSetOld->Size() == aTextureSetNew->Size())))
3929     {
3930       aTextureSetNew = aTextureSetOld;
3931     }
3932
3933     if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
3934      && aTexturedShape.IsNull())
3935     {
3936       aTexturedIO->SetToUpdate();
3937     }
3938
3939     toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
3940     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
3941     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
3942     aTextureSetOld.Nullify();
3943   }
3944
3945   if (toSetDefaults)
3946   {
3947     if (toModulate != -1)
3948     {
3949       toModulate = 1;
3950     }
3951     if (!toSetFilter)
3952     {
3953       toSetFilter = true;
3954       aFilter     = Graphic3d_TOTF_BILINEAR;
3955     }
3956     if (!toSetAniso)
3957     {
3958       toSetAniso    = true;
3959       anAnisoFilter = Graphic3d_LOTA_OFF;
3960     }
3961     if (!toSetTrsfAngle)
3962     {
3963       toSetTrsfAngle = true;
3964       aTrsfRotAngle  = 0.0f;
3965     }
3966     if (!toSetTrsfTrans)
3967     {
3968       toSetTrsfTrans = true;
3969       aTrsfTrans = Graphic3d_Vec2 (0.0f, 0.0f);
3970     }
3971     if (!toSetTrsfScale)
3972     {
3973       toSetTrsfScale = true;
3974       aTrsfScale = Graphic3d_Vec2 (1.0f, 1.0f);
3975     }
3976   }
3977
3978   if (aCommandName == "vtexture"
3979    && theArgsNb == 2)
3980   {
3981     if (!aTextureSetOld.IsNull())
3982     {
3983       //toComputeUV = true; // we can keep UV vertex attributes
3984       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
3985       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
3986       aTextureSetOld.Nullify();
3987     }
3988   }
3989
3990   if (aTexturedIO->Attributes()->HasOwnShadingAspect()
3991   && !aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap().IsNull())
3992   {
3993     if (toModulate != -1)
3994     {
3995       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetModulate (toModulate == 1);
3996     }
3997     if (toSetTrsfAngle)
3998     {
3999       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetRotation (aTrsfRotAngle); // takes degrees
4000     }
4001     if (toSetTrsfTrans)
4002     {
4003       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetTranslation (aTrsfTrans);
4004     }
4005     if (toSetTrsfScale)
4006     {
4007       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetScale (aTrsfScale);
4008     }
4009     if (toSetFilter)
4010     {
4011       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetFilter (aFilter);
4012     }
4013     if (toSetAniso)
4014     {
4015       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetAnisoFilter (anAnisoFilter);
4016     }
4017   }
4018
4019   // set default values if requested
4020   if (!toSetGenRepeat
4021    && (aCommandName == "vtexrepeat"
4022     || toSetDefaults))
4023   {
4024     if (!aTexturedShape.IsNull())
4025     {
4026       aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4027     }
4028     toSetGenRepeat = true;
4029   }
4030   if (!toSetGenOrigin
4031    && (aCommandName == "vtexorigin"
4032     || toSetDefaults))
4033   {
4034     if (!aTexturedShape.IsNull())
4035     {
4036       aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4037     }
4038     toSetGenOrigin = true;
4039   }
4040   if (!toSetGenScale
4041    && (aCommandName == "vtexscale"
4042     || toSetDefaults))
4043   {
4044     if (!aTexturedShape.IsNull())
4045     {
4046       aTexturedShape->SetTextureScaleUV  (gp_Pnt2d (1.0, 1.0));
4047     }
4048     toSetGenScale = true;
4049   }
4050
4051   if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
4052   {
4053     if (!aTexturedShape.IsNull())
4054     {
4055       aTexturedShape->SetToUpdate (AIS_Shaded);
4056       if (toSetImage)
4057       {
4058         if ((aTexturedIO->HasDisplayMode() && aTexturedIO->DisplayMode() != AIS_Shaded)
4059          || aCtx->DisplayMode() != AIS_Shaded)
4060         {
4061           aCtx->SetDisplayMode (aTexturedIO, AIS_Shaded, false);
4062         }
4063       }
4064     }
4065   }
4066   aCtx->Display (aTexturedIO, false);
4067   aTexturedIO->SynchronizeAspects();
4068   return 0;
4069 }
4070
4071 //! Auxiliary method to parse transformation persistence flags
4072 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
4073                                            Graphic3d_TransModeFlags&      theFlags)
4074 {
4075   if (theFlagString == "zoom")
4076   {
4077     theFlags = Graphic3d_TMF_ZoomPers;
4078   }
4079   else if (theFlagString == "rotate")
4080   {
4081     theFlags = Graphic3d_TMF_RotatePers;
4082   }
4083   else if (theFlagString == "zoomrotate")
4084   {
4085     theFlags = Graphic3d_TMF_ZoomRotatePers;
4086   }
4087   else if (theFlagString == "trihedron"
4088         || theFlagString == "triedron")
4089   {
4090     theFlags = Graphic3d_TMF_TriedronPers;
4091   }
4092   else if (theFlagString == "none")
4093   {
4094     theFlags = Graphic3d_TMF_None;
4095   }
4096   else
4097   {
4098     return Standard_False;
4099   }
4100
4101   return Standard_True;
4102 }
4103
4104 //! Auxiliary method to parse transformation persistence flags
4105 inline Standard_Boolean parseTrsfPersCorner (const TCollection_AsciiString& theString,
4106                                              Aspect_TypeOfTriedronPosition& theCorner)
4107 {
4108   TCollection_AsciiString aString (theString);
4109   aString.LowerCase();
4110   if (aString == "center")
4111   {
4112     theCorner = Aspect_TOTP_CENTER;
4113   }
4114   else if (aString == "top"
4115         || aString == "upper")
4116   {
4117     theCorner = Aspect_TOTP_TOP;
4118   }
4119   else if (aString == "bottom"
4120         || aString == "lower")
4121   {
4122     theCorner = Aspect_TOTP_BOTTOM;
4123   }
4124   else if (aString == "left")
4125   {
4126     theCorner = Aspect_TOTP_LEFT;
4127   }
4128   else if (aString == "right")
4129   {
4130     theCorner = Aspect_TOTP_RIGHT;
4131   }
4132   else if (aString == "topleft"
4133         || aString == "leftupper"
4134         || aString == "upperleft")
4135   {
4136     theCorner = Aspect_TOTP_LEFT_UPPER;
4137   }
4138   else if (aString == "bottomleft"
4139         || aString == "leftlower"
4140         || aString == "lowerleft")
4141   {
4142     theCorner = Aspect_TOTP_LEFT_LOWER;
4143   }
4144   else if (aString == "topright"
4145         || aString == "rightupper"
4146         || aString == "upperright")
4147   {
4148     theCorner = Aspect_TOTP_RIGHT_UPPER;
4149   }
4150   else if (aString == "bottomright"
4151         || aString == "lowerright"
4152         || aString == "rightlower")
4153   {
4154     theCorner = Aspect_TOTP_RIGHT_LOWER;
4155   }
4156   else
4157   {
4158     return Standard_False;
4159   }
4160
4161   return Standard_True;
4162 }
4163
4164 //==============================================================================
4165 //function : VDisplay2
4166 //author   : ege
4167 //purpose  : Display an object from its name
4168 //==============================================================================
4169 static int VDisplay2 (Draw_Interpretor& theDI,
4170                       Standard_Integer  theArgNb,
4171                       const char**      theArgVec)
4172 {
4173   if (theArgNb < 2)
4174   {
4175     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
4176     return 1;
4177   }
4178
4179   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
4180   if (aCtx.IsNull())
4181   {
4182     ViewerTest::ViewerInit();
4183     aCtx = ViewerTest::GetAISContext();
4184   }
4185
4186   // Parse input arguments
4187   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4188   Standard_Integer   isMutable      = -1;
4189   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
4190   Standard_Boolean   toReDisplay    = Standard_False;
4191   Standard_Integer   isSelectable   = -1;
4192   Standard_Integer   anObjDispMode  = -2;
4193   Standard_Integer   anObjHighMode  = -2;
4194   Standard_Boolean   toSetTrsfPers  = Standard_False;
4195   Handle(Graphic3d_TransformPers) aTrsfPers;
4196   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
4197   AIS_DisplayStatus aDispStatus = AIS_DS_None;
4198   Standard_Integer toDisplayInView = Standard_False;
4199   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4200   {
4201     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4202     TCollection_AsciiString       aNameCase = aName;
4203     aNameCase.LowerCase();
4204     if (anUpdateTool.parseRedrawMode (aName))
4205     {
4206       continue;
4207     }
4208     else if (aNameCase == "-mutable")
4209     {
4210       isMutable = 1;
4211     }
4212     else if (aNameCase == "-neutral")
4213     {
4214       aDispStatus = AIS_DS_Displayed;
4215     }
4216     else if (aNameCase == "-immediate"
4217           || aNameCase == "-top")
4218     {
4219       aZLayer = Graphic3d_ZLayerId_Top;
4220     }
4221     else if (aNameCase == "-topmost")
4222     {
4223       aZLayer = Graphic3d_ZLayerId_Topmost;
4224     }
4225     else if (aNameCase == "-osd"
4226           || aNameCase == "-toposd"
4227           || aNameCase == "-overlay")
4228     {
4229       aZLayer = Graphic3d_ZLayerId_TopOSD;
4230     }
4231     else if (aNameCase == "-botosd"
4232           || aNameCase == "-underlay")
4233     {
4234       aZLayer = Graphic3d_ZLayerId_BotOSD;
4235     }
4236     else if (aNameCase == "-select"
4237           || aNameCase == "-selectable")
4238     {
4239       isSelectable = 1;
4240     }
4241     else if (aNameCase == "-noselect"
4242           || aNameCase == "-noselection")
4243     {
4244       isSelectable = 0;
4245     }
4246     else if (aNameCase == "-dispmode"
4247           || aNameCase == "-displaymode")
4248     {
4249       if (++anArgIter >= theArgNb)
4250       {
4251         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4252         return 1;
4253       }
4254
4255       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
4256     }
4257     else if (aNameCase == "-highmode"
4258           || aNameCase == "-highlightmode")
4259     {
4260       if (++anArgIter >= theArgNb)
4261       {
4262         std::cerr << "Error: wrong syntax at " << aName << ".\n";
4263         return 1;
4264       }
4265
4266       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
4267     }
4268     else if (aNameCase == "-3d")
4269     {
4270       toSetTrsfPers  = Standard_True;
4271       aTrsfPers.Nullify();
4272     }
4273     else if (aNameCase == "-2d"
4274           || aNameCase == "-trihedron"
4275           || aNameCase == "-triedron")
4276     {
4277       toSetTrsfPers  = Standard_True;
4278       aTrsfPers = new Graphic3d_TransformPers (aNameCase == "-2d" ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4279
4280       if (anArgIter + 1 < theArgNb)
4281       {
4282         Aspect_TypeOfTriedronPosition aCorner = Aspect_TOTP_CENTER;
4283         if (parseTrsfPersCorner (theArgVec[anArgIter + 1], aCorner))
4284         {
4285           ++anArgIter;
4286           aTrsfPers->SetCorner2d (aCorner);
4287
4288           if (anArgIter + 2 < theArgNb)
4289           {
4290             TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
4291             TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
4292             if (anX.IsIntegerValue()
4293              && anY.IsIntegerValue())
4294             {
4295               anArgIter += 2;
4296               aTrsfPers->SetOffset2d (Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue()));
4297 &n