0030337: Draw Harness, ViewerTest - do not restrict vtexture to AIS_Shape
[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 //function : ParseColor
98 //purpose  :
99 //=======================================================================
100
101 Standard_Integer ViewerTest::ParseColor (Standard_Integer  theArgNb,
102                                          const char**      theArgVec,
103                                          Quantity_Color&   theColor)
104 {
105   Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
106   if (theArgNb >= 1
107    && Quantity_Color::ColorFromName (theArgVec[0], aColor))
108   {
109     theColor = aColor;
110     return 1;
111   }
112   else if (theArgNb >= 3)
113   {
114     const TCollection_AsciiString anRgbStr[3] =
115     {
116       theArgVec[0],
117       theArgVec[1],
118       theArgVec[2]
119     };
120     if (!anRgbStr[0].IsRealValue()
121      || !anRgbStr[1].IsRealValue()
122      || !anRgbStr[2].IsRealValue())
123     {
124       return 0;
125     }
126
127     Graphic3d_Vec4d anRgb;
128     anRgb.x() = anRgbStr[0].RealValue();
129     anRgb.y() = anRgbStr[1].RealValue();
130     anRgb.z() = anRgbStr[2].RealValue();
131     if (anRgb.x() < 0.0 || anRgb.x() > 1.0
132      || anRgb.y() < 0.0 || anRgb.y() > 1.0
133      || anRgb.z() < 0.0 || anRgb.z() > 1.0)
134     {
135       std::cout << "Error: RGB color values should be within range 0..1!\n";
136       return 0;
137     }
138
139     theColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
140     return 3;
141   }
142
143   return 0;
144 }
145
146 //=======================================================================
147 //function : ParseOnOff
148 //purpose  :
149 //=======================================================================
150 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
151                                          Standard_Boolean& theIsOn)
152 {
153   TCollection_AsciiString aFlag(theArg);
154   aFlag.LowerCase();
155   if (aFlag == "on"
156    || aFlag == "1")
157   {
158     theIsOn = Standard_True;
159     return Standard_True;
160   }
161   else if (aFlag == "off"
162         || aFlag == "0")
163   {
164     theIsOn = Standard_False;
165     return Standard_True;
166   }
167   return Standard_False;
168 }
169
170 //=======================================================================
171 //function : GetSelectedShapes
172 //purpose  :
173 //=======================================================================
174 void ViewerTest::GetSelectedShapes (TopTools_ListOfShape& theSelectedShapes)
175 {
176   for (GetAISContext()->InitSelected(); GetAISContext()->MoreSelected(); GetAISContext()->NextSelected())
177   {
178     TopoDS_Shape aShape = GetAISContext()->SelectedShape();
179     if (!aShape.IsNull())
180     {
181       theSelectedShapes.Append (aShape);
182     }
183   }
184 }
185
186 //=======================================================================
187 //function : ParseLineType
188 //purpose  :
189 //=======================================================================
190 Standard_Boolean ViewerTest::ParseLineType (Standard_CString   theArg,
191                                             Aspect_TypeOfLine& theType)
192 {
193   TCollection_AsciiString aTypeStr (theArg);
194   aTypeStr.LowerCase();
195   if (aTypeStr == "empty")
196   {
197     theType = Aspect_TOL_EMPTY;
198   }
199   else if (aTypeStr == "solid")
200   {
201     theType = Aspect_TOL_SOLID;
202   }
203   else if (aTypeStr == "dot")
204   {
205     theType = Aspect_TOL_DOT;
206   }
207   else if (aTypeStr == "dash")
208   {
209     theType = Aspect_TOL_DASH;
210   }
211   else if (aTypeStr == "dotdash")
212   {
213     theType = Aspect_TOL_DOTDASH;
214   }
215   else
216   {
217     const int aTypeInt = Draw::Atoi (theArg);
218     if (aTypeInt < -1 || aTypeInt >= Aspect_TOL_USERDEFINED)
219     {
220       return Standard_False;
221     }
222     theType = (Aspect_TypeOfLine )aTypeInt;
223   }
224   return Standard_True;
225 }
226
227 //=======================================================================
228 //function : ParseMarkerType
229 //purpose  :
230 //=======================================================================
231 Standard_Boolean ViewerTest::ParseMarkerType (Standard_CString theArg,
232                                               Aspect_TypeOfMarker& theType,
233                                               Handle(Image_PixMap)& theImage)
234 {
235   theImage.Nullify();
236   TCollection_AsciiString aTypeStr (theArg);
237   aTypeStr.LowerCase();
238   if (aTypeStr == "empty")
239   {
240     theType = Aspect_TOM_EMPTY;
241   }
242   else if (aTypeStr == "point"
243         || aTypeStr == "dot"
244         || aTypeStr == ".")
245   {
246     theType = Aspect_TOM_POINT;
247   }
248   else if (aTypeStr == "plus"
249         || aTypeStr == "+")
250   {
251     theType = Aspect_TOM_PLUS;
252   }
253   else if (aTypeStr == "star"
254         || aTypeStr == "*")
255   {
256     theType = Aspect_TOM_STAR;
257   }
258   else if (aTypeStr == "cross"
259         || aTypeStr == "x")
260   {
261     theType = Aspect_TOM_X;
262   }
263   else if (aTypeStr == "circle"
264         || aTypeStr == "o")
265   {
266     theType = Aspect_TOM_O;
267   }
268   else if (aTypeStr == "pointincircle")
269   {
270     theType = Aspect_TOM_O_POINT;
271   }
272   else if (aTypeStr == "plusincircle")
273   {
274     theType = Aspect_TOM_O_PLUS;
275   }
276   else if (aTypeStr == "starincircle")
277   {
278     theType = Aspect_TOM_O_STAR;
279   }
280   else if (aTypeStr == "crossincircle"
281         || aTypeStr == "xcircle")
282   {
283     theType = Aspect_TOM_O_X;
284   }
285   else if (aTypeStr == "ring1")
286   {
287     theType = Aspect_TOM_RING1;
288   }
289   else if (aTypeStr == "ring2")
290   {
291     theType = Aspect_TOM_RING2;
292   }
293   else if (aTypeStr == "ring"
294         || aTypeStr == "ring3")
295   {
296     theType = Aspect_TOM_RING3;
297   }
298   else if (aTypeStr == "ball")
299   {
300     theType = Aspect_TOM_BALL;
301   }
302   else if (aTypeStr.IsIntegerValue())
303   {
304     const int aTypeInt = aTypeStr.IntegerValue();
305     if (aTypeInt < -1 || aTypeInt >= Aspect_TOM_USERDEFINED)
306     {
307       return Standard_False;
308     }
309     theType = (Aspect_TypeOfMarker )aTypeInt;
310   }
311   else
312   {
313     theType = Aspect_TOM_USERDEFINED;
314     Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
315     if (!anImage->Load (theArg))
316     {
317       return Standard_False;
318     }
319     if (anImage->Format() == Image_Format_Gray)
320     {
321       anImage->SetFormat (Image_Format_Alpha);
322     }
323     else if (anImage->Format() == Image_Format_GrayF)
324     {
325       anImage->SetFormat (Image_Format_AlphaF);
326     }
327     theImage = anImage;
328   }
329   return Standard_True;
330 }
331
332 //=======================================================================
333 //function : ParseShadingModel
334 //purpose  :
335 //=======================================================================
336 Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString              theArg,
337                                                 Graphic3d_TypeOfShadingModel& theModel)
338 {
339   TCollection_AsciiString aTypeStr (theArg);
340   aTypeStr.LowerCase();
341   if (aTypeStr == "unlit"
342    || aTypeStr == "color"
343    || aTypeStr == "none")
344   {
345     theModel = Graphic3d_TOSM_UNLIT;
346   }
347   else if (aTypeStr == "flat"
348         || aTypeStr == "facet")
349   {
350     theModel = Graphic3d_TOSM_FACET;
351   }
352   else if (aTypeStr == "gouraud"
353         || aTypeStr == "vertex"
354         || aTypeStr == "vert")
355   {
356     theModel = Graphic3d_TOSM_VERTEX;
357   }
358   else if (aTypeStr == "phong"
359         || aTypeStr == "fragment"
360         || aTypeStr == "frag"
361         || aTypeStr == "pixel")
362   {
363     theModel = Graphic3d_TOSM_FRAGMENT;
364   }
365   else if (aTypeStr == "default"
366         || aTypeStr == "def")
367   {
368     theModel = Graphic3d_TOSM_DEFAULT;
369   }
370   else if (aTypeStr.IsIntegerValue())
371   {
372     const int aTypeInt = aTypeStr.IntegerValue();
373     if (aTypeInt <= Graphic3d_TOSM_DEFAULT || aTypeInt >= Graphic3d_TypeOfShadingModel_NB)
374     {
375       return Standard_False;
376     }
377     theModel = (Graphic3d_TypeOfShadingModel)aTypeInt;
378   }
379   else
380   {
381     return Standard_False;
382   }
383   return Standard_True;
384 }
385
386 //=======================================================================
387 //function : GetTypeNames
388 //purpose  :
389 //=======================================================================
390 static const char** GetTypeNames()
391 {
392   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
393                           "Shape","ConnectedShape","MultiConn.Shape",
394                           "ConnectedInter.","MultiConn.",
395                           "Constraint","Dimension"};
396   static const char** ThePointer = names;
397   return ThePointer;
398 }
399
400 //=======================================================================
401 //function : GetTypeAndSignfromString
402 //purpose  :
403 //=======================================================================
404 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
405 {
406   const char ** thefullnames = GetTypeNames();
407   Standard_Integer index(-1);
408
409   for(Standard_Integer i=0;i<=13 && index==-1;i++)
410     if(!strcasecmp(name,thefullnames[i]))
411       index = i;
412
413   if(index ==-1){
414     TheType = AIS_KOI_None;
415     TheSign = -1;
416     return;
417   }
418
419   if(index<=6){
420     TheType = AIS_KOI_Datum;
421     TheSign = index+1;
422   }
423   else if (index <=9){
424     TheType = AIS_KOI_Shape;
425     TheSign = index-7;
426   }
427   else if(index<=11){
428     TheType = AIS_KOI_Object;
429     TheSign = index-10;
430   }
431   else{
432     TheType = AIS_KOI_Relation;
433     TheSign = index-12;
434   }
435
436 }
437
438
439
440 #include <string.h>
441 #include <Draw_Interpretor.hxx>
442 #include <Draw.hxx>
443 #include <Draw_Appli.hxx>
444 #include <DBRep.hxx>
445
446
447 #include <TCollection_AsciiString.hxx>
448 #include <V3d_Viewer.hxx>
449 #include <V3d_View.hxx>
450 #include <V3d.hxx>
451
452 #include <AIS_InteractiveContext.hxx>
453 #include <AIS_Shape.hxx>
454 #include <AIS_DisplayMode.hxx>
455 #include <TColStd_MapOfInteger.hxx>
456 #include <AIS_MapOfInteractive.hxx>
457 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
458 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
459 #include <ViewerTest_EventManager.hxx>
460
461 #include <TopoDS_Solid.hxx>
462 #include <BRepTools.hxx>
463 #include <BRep_Builder.hxx>
464 #include <TopAbs_ShapeEnum.hxx>
465
466 #include <TopoDS.hxx>
467 #include <BRep_Tool.hxx>
468
469
470 #include <Draw_Window.hxx>
471 #include <AIS_ListIteratorOfListOfInteractive.hxx>
472 #include <AIS_ListOfInteractive.hxx>
473 #include <AIS_DisplayMode.hxx>
474 #include <TopTools_ListOfShape.hxx>
475 #include <BRepOffsetAPI_MakeThickSolid.hxx>
476
477 //==============================================================================
478 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
479 //==============================================================================
480 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
481   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
482   return TheMap;
483 }
484
485 //=======================================================================
486 //function : Display
487 //purpose  :
488 //=======================================================================
489 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
490                                       const Handle(AIS_InteractiveObject)& theObject,
491                                       const Standard_Boolean               theToUpdate,
492                                       const Standard_Boolean               theReplaceIfExists)
493 {
494   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
495   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
496   if (aCtx.IsNull())
497   {
498     std::cout << "Error: AIS context is not available.\n";
499     return Standard_False;
500   }
501
502   if (aMap.IsBound2 (theName))
503   {
504     if (!theReplaceIfExists)
505     {
506       std::cout << "Error: other interactive object has been already registered with name: " << theName << ".\n"
507                 << "Please use another name.\n";
508       return Standard_False;
509     }
510
511     if (Handle(AIS_InteractiveObject) anOldObj = aMap.Find2 (theName))
512     {
513       aCtx->Remove (anOldObj, theObject.IsNull() && theToUpdate);
514     }
515     aMap.UnBind2 (theName);
516   }
517
518   if (theObject.IsNull())
519   {
520     // object with specified name has been already unbound
521     return Standard_True;
522   }
523
524   // unbind AIS object if it was bound with another name
525   aMap.UnBind1 (theObject);
526
527   // can be registered without rebinding
528   aMap.Bind (theObject, theName);
529   aCtx->Display (theObject, theToUpdate);
530   return Standard_True;
531 }
532
533 //! Alias for ViewerTest::Display(), compatibility with old code.
534 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
535                                                     const Handle(AIS_InteractiveObject)& theObject,
536                                                     Standard_Boolean theReplaceIfExists = Standard_True)
537 {
538   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
539 }
540
541 static TColStd_MapOfInteger theactivatedmodes(8);
542 static TColStd_ListOfTransient theEventMgrs;
543
544 static void VwrTst_InitEventMgr(const Handle(V3d_View)& aView,
545                                 const Handle(AIS_InteractiveContext)& Ctx)
546 {
547   theEventMgrs.Clear();
548   theEventMgrs.Prepend(new ViewerTest_EventManager(aView, Ctx));
549 }
550
551 static Handle(V3d_View)&  a3DView()
552 {
553   static Handle(V3d_View) Viou;
554   return Viou;
555 }
556
557
558 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
559   static Handle(AIS_InteractiveContext) aContext;
560   return aContext;
561 }
562
563 const Handle(V3d_View)& ViewerTest::CurrentView()
564 {
565   return a3DView();
566 }
567 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
568 {
569   a3DView() = V;
570 }
571
572 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
573 {
574   return TheAISContext();
575 }
576
577 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
578 {
579   TheAISContext() = aCtx;
580   ViewerTest::ResetEventManager();
581 }
582
583 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
584 {
585   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
586 }
587
588 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
589 {
590   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
591 }
592
593
594 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
595   theEventMgrs.Prepend(EM);
596 }
597
598 void ViewerTest::UnsetEventManager()
599 {
600   theEventMgrs.RemoveFirst();
601 }
602
603
604 void ViewerTest::ResetEventManager()
605 {
606   const Handle(V3d_View) aView = ViewerTest::CurrentView();
607   VwrTst_InitEventMgr(aView, ViewerTest::GetAISContext());
608 }
609
610 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
611 {
612   Handle(ViewerTest_EventManager) EM;
613   if(theEventMgrs.IsEmpty()) return EM;
614   Handle(Standard_Transient) Tr =  theEventMgrs.First();
615   EM = Handle(ViewerTest_EventManager)::DownCast (Tr);
616   return EM;
617 }
618
619 //=======================================================================
620 //function : Get Context and active view
621 //purpose  :
622 //=======================================================================
623 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
624                                        Handle(V3d_View)&               theView)
625 {
626   theCtx  = ViewerTest::GetAISContext();
627   theView = ViewerTest::CurrentView();
628   if (theCtx.IsNull()
629    || theView.IsNull())
630   {
631     std::cout << "Error: cannot find an active view!\n";
632     return Standard_False;
633   }
634   return Standard_True;
635 }
636
637 //==============================================================================
638 //function : GetShapeFromName
639 //purpose  : Compute an Shape from a draw variable or a file name
640 //==============================================================================
641
642 static TopoDS_Shape GetShapeFromName(const char* name)
643 {
644   TopoDS_Shape S = DBRep::Get(name);
645
646   if ( S.IsNull() ) {
647         BRep_Builder aBuilder;
648         BRepTools::Read( S, name, aBuilder);
649   }
650
651   return S;
652 }
653
654 //==============================================================================
655 //function : GetAISShapeFromName
656 //purpose  : Compute an AIS_Shape from a draw variable or a file name
657 //==============================================================================
658 Handle(AIS_Shape) GetAISShapeFromName(const char* name)
659 {
660   Handle(AIS_InteractiveObject) aPrs;
661   if (GetMapOfAIS().Find2 (name, aPrs)
662   && !aPrs.IsNull())
663   {
664     if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs))
665     {
666       return aShapePrs;
667     }
668
669     std::cout << "an Object which is not an AIS_Shape already has this name!!!\n";
670     return Handle(AIS_Shape)();
671   }
672
673   TopoDS_Shape aShape = GetShapeFromName (name);
674   if (!aShape.IsNull())
675   {
676     return new AIS_Shape(aShape);
677   }
678   return Handle(AIS_Shape)();
679 }
680
681
682 //==============================================================================
683 //function : Clear
684 //purpose  : Remove all the object from the viewer
685 //==============================================================================
686 void ViewerTest::Clear()
687 {
688   if (a3DView().IsNull())
689   {
690     return;
691   }
692
693   NCollection_Sequence<Handle(AIS_InteractiveObject)> aListRemoved;
694   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS()); anObjIter.More(); anObjIter.Next())
695   {
696     const Handle(AIS_InteractiveObject) anObj = anObjIter.Key1();
697     if (anObj->GetContext() != TheAISContext())
698     {
699       continue;
700     }
701
702     std::cout << "Remove " << anObjIter.Key2() << std::endl;
703     TheAISContext()->Remove (anObj, Standard_False);
704     aListRemoved.Append (anObj);
705   }
706
707   TheAISContext()->RebuildSelectionStructs();
708   TheAISContext()->UpdateCurrentViewer();
709   if (aListRemoved.Size() == GetMapOfAIS().Extent())
710   {
711     GetMapOfAIS().Clear();
712   }
713   else
714   {
715     for (NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator anObjIter (aListRemoved); anObjIter.More(); anObjIter.Next())
716     {
717       GetMapOfAIS().UnBind1 (anObjIter.Value());
718     }
719   }
720 }
721
722 //==============================================================================
723 //function : CopyIsoAspect
724 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
725 //==============================================================================
726 static Handle(Prs3d_IsoAspect) CopyIsoAspect
727       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
728        const Standard_Integer theNbIsos)
729 {
730   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
731   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
732   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
733
734   Handle(Prs3d_IsoAspect) aResult =
735     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
736
737   return aResult;
738 }
739
740 //==============================================================================
741 //function : visos
742 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
743 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
744 //==============================================================================
745 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
746 {
747   if (TheAISContext().IsNull()) {
748     di << argv[0] << " Call 'vinit' before!\n";
749     return 1;
750   }
751
752   if (argc <= 1) {
753     di << "Current number of isos : " <<
754       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
755       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
756     di << "IsoOnPlane mode is " <<
757       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
758     di << "IsoOnTriangulation mode is " <<
759       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
760     return 0;
761   }
762
763   Standard_Integer aLastInd = argc - 1;
764   Standard_Boolean isChanged = Standard_False;
765   Standard_Integer aNbUIsos = 0;
766   Standard_Integer aNbVIsos = 0;
767
768   if (aLastInd >= 3) {
769     Standard_Boolean isIsoOnPlane = Standard_False;
770
771     if (strcmp(argv[aLastInd], "1") == 0) {
772       isIsoOnPlane = Standard_True;
773       isChanged    = Standard_True;
774     } else if (strcmp(argv[aLastInd], "0") == 0) {
775       isIsoOnPlane = Standard_False;
776       isChanged    = Standard_True;
777     }
778
779     if (isChanged) {
780       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
781       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
782       aLastInd -= 3;
783
784       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
785       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
786
787       TheAISContext()->IsoOnPlane(isIsoOnPlane);
788
789       if (aLastInd == 0) {
790         // If there are no shapes provided set the default numbers.
791         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
792         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
793       }
794     }
795   }
796
797   Standard_Integer i;
798
799   for (i = 1; i <= aLastInd; i++)
800   {
801     TCollection_AsciiString name(argv[i]);
802     Handle(AIS_InteractiveObject) aShape;
803     GetMapOfAIS().Find2(name, aShape);
804     if (aShape.IsNull())
805     {
806       std::cout << "Syntax error: object '" << name << "' is not found\n";
807       return 1;
808     }
809
810     Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
811     Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
812     Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
813     if (isChanged)
814     {
815       CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
816       CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
817       TheAISContext()->SetLocalAttributes (aShape, CurDrawer, Standard_False);
818       TheAISContext()->Redisplay (aShape, Standard_False);
819     }
820     else
821     {
822       di << "Number of isos for " << argv[i] << " : "
823           << aUIso->Number() << " " << aVIso->Number() << "\n";
824     }
825   }
826
827   if (isChanged) {
828     TheAISContext()->UpdateCurrentViewer();
829   }
830
831   return 0;
832 }
833
834 static Standard_Integer VDispSensi (Draw_Interpretor& ,
835                                     Standard_Integer  theArgNb,
836                                     Standard_CString* )
837 {
838   if (theArgNb > 1)
839   {
840     std::cout << "Error: wrong syntax!\n";
841     return 1;
842   }
843
844   Handle(AIS_InteractiveContext) aCtx;
845   Handle(V3d_View)               aView;
846   if (!getCtxAndView (aCtx, aView))
847   {
848     return 1;
849   }
850
851   aCtx->DisplayActiveSensitive (aView);
852   return 0;
853
854 }
855
856 static Standard_Integer VClearSensi (Draw_Interpretor& ,
857                                      Standard_Integer  theArgNb,
858                                      Standard_CString* )
859 {
860   if (theArgNb > 1)
861   {
862     std::cout << "Error: wrong syntax!\n";
863     return 1;
864   }
865
866   Handle(AIS_InteractiveContext) aCtx;
867   Handle(V3d_View)               aView;
868   if (!getCtxAndView (aCtx, aView))
869   {
870     return 1;
871   }
872   aCtx->ClearActiveSensitive (aView);
873   return 0;
874 }
875
876 //==============================================================================
877 //function : VDir
878 //purpose  : To list the displayed object with their attributes
879 //==============================================================================
880 static int VDir (Draw_Interpretor& theDI,
881                  Standard_Integer ,
882                  const char** )
883 {
884   if (!a3DView().IsNull())
885   {
886     return 0;
887   }
888
889   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
890        anIter.More(); anIter.Next())
891   {
892     theDI << "\t" << anIter.Key2().ToCString() << "\n";
893   }
894   return 0;
895 }
896
897 //! Auxiliary enumeration
898 enum ViewerTest_StereoPair
899 {
900   ViewerTest_SP_Single,
901   ViewerTest_SP_SideBySide,
902   ViewerTest_SP_OverUnder
903 };
904
905 //==============================================================================
906 //function : VDump
907 //purpose  : To dump the active view snapshot to image file
908 //==============================================================================
909 static Standard_Integer VDump (Draw_Interpretor& theDI,
910                                Standard_Integer  theArgNb,
911                                Standard_CString* theArgVec)
912 {
913   if (theArgNb < 2)
914   {
915     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
916     return 1;
917   }
918
919   Standard_Integer      anArgIter   = 1;
920   Standard_CString      aFilePath   = theArgVec[anArgIter++];
921   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
922   V3d_ImageDumpOptions  aParams;
923   aParams.BufferType    = Graphic3d_BT_RGB;
924   aParams.StereoOptions = V3d_SDO_MONO;
925   for (; anArgIter < theArgNb; ++anArgIter)
926   {
927     TCollection_AsciiString anArg (theArgVec[anArgIter]);
928     anArg.LowerCase();
929     if (anArg == "-buffer")
930     {
931       if (++anArgIter >= theArgNb)
932       {
933         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
934         return 1;
935       }
936
937       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
938       aBufArg.LowerCase();
939       if (aBufArg == "rgba")
940       {
941         aParams.BufferType = Graphic3d_BT_RGBA;
942       }
943       else if (aBufArg == "rgb")
944       {
945         aParams.BufferType = Graphic3d_BT_RGB;
946       }
947       else if (aBufArg == "depth")
948       {
949         aParams.BufferType = Graphic3d_BT_Depth;
950       }
951       else
952       {
953         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
954         return 1;
955       }
956     }
957     else if (anArg == "-stereo")
958     {
959       if (++anArgIter >= theArgNb)
960       {
961         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
962         return 1;
963       }
964
965       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
966       aStereoArg.LowerCase();
967       if (aStereoArg == "l"
968        || aStereoArg == "left")
969       {
970         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
971       }
972       else if (aStereoArg == "r"
973             || aStereoArg == "right")
974       {
975         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
976       }
977       else if (aStereoArg == "mono")
978       {
979         aParams.StereoOptions = V3d_SDO_MONO;
980       }
981       else if (aStereoArg == "blended"
982             || aStereoArg == "blend"
983             || aStereoArg == "stereo")
984       {
985         aParams.StereoOptions = V3d_SDO_BLENDED;
986       }
987       else if (aStereoArg == "sbs"
988             || aStereoArg == "sidebyside")
989       {
990         aStereoPair = ViewerTest_SP_SideBySide;
991       }
992       else if (aStereoArg == "ou"
993             || aStereoArg == "overunder")
994       {
995         aStereoPair = ViewerTest_SP_OverUnder;
996       }
997       else
998       {
999         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
1000         return 1;
1001       }
1002     }
1003     else if (anArg == "-rgba"
1004           || anArg ==  "rgba")
1005     {
1006       aParams.BufferType = Graphic3d_BT_RGBA;
1007     }
1008     else if (anArg == "-rgb"
1009           || anArg ==  "rgb")
1010     {
1011       aParams.BufferType = Graphic3d_BT_RGB;
1012     }
1013     else if (anArg == "-depth"
1014           || anArg ==  "depth")
1015     {
1016       aParams.BufferType = Graphic3d_BT_Depth;
1017     }
1018     else if (anArg == "-width"
1019           || anArg ==  "width"
1020           || anArg ==  "sizex")
1021     {
1022       if (aParams.Width != 0)
1023       {
1024         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1025         return 1;
1026       }
1027       else if (++anArgIter >= theArgNb)
1028       {
1029         std::cout << "Error: integer value is expected right after 'width'\n";
1030         return 1;
1031       }
1032       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
1033     }
1034     else if (anArg == "-height"
1035           || anArg ==  "height"
1036           || anArg ==  "-sizey")
1037     {
1038       if (aParams.Height != 0)
1039       {
1040         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
1041         return 1;
1042       }
1043       else if (++anArgIter >= theArgNb)
1044       {
1045         std::cout << "Error: integer value is expected right after 'height'\n";
1046         return 1;
1047       }
1048       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
1049     }
1050     else if (anArg == "-tile"
1051           || anArg == "-tilesize")
1052     {
1053       if (++anArgIter >= theArgNb)
1054       {
1055         std::cout << "Error: integer value is expected right after 'tileSize'\n";
1056         return 1;
1057       }
1058       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
1059     }
1060     else
1061     {
1062       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
1063       return 1;
1064     }
1065   }
1066   if ((aParams.Width <= 0 && aParams.Height >  0)
1067    || (aParams.Width >  0 && aParams.Height <= 0))
1068   {
1069     std::cout << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect\n";
1070     return 1;
1071   }
1072
1073   Handle(V3d_View) aView = ViewerTest::CurrentView();
1074   if (aView.IsNull())
1075   {
1076     std::cout << "Error: cannot find an active view!\n";
1077     return 1;
1078   }
1079
1080   if (aParams.Width <= 0 || aParams.Height <= 0)
1081   {
1082     aView->Window()->Size (aParams.Width, aParams.Height);
1083   }
1084
1085   Image_AlienPixMap aPixMap;
1086   Image_Format aFormat = Image_Format_UNKNOWN;
1087   switch (aParams.BufferType)
1088   {
1089     case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
1090     case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
1091     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
1092     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
1093   }
1094
1095   switch (aStereoPair)
1096   {
1097     case ViewerTest_SP_Single:
1098     {
1099       if (!aView->ToPixMap (aPixMap, aParams))
1100       {
1101         theDI << "Fail: view dump failed!\n";
1102         return 0;
1103       }
1104       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
1105             || aPixMap.SizeY() != Standard_Size(aParams.Height))
1106       {
1107         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
1108               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
1109       }
1110       break;
1111     }
1112     case ViewerTest_SP_SideBySide:
1113     {
1114       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
1115       {
1116         theDI << "Fail: not enough memory for image allocation!\n";
1117         return 0;
1118       }
1119
1120       Image_PixMap aPixMapL, aPixMapR;
1121       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1122                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1123       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1124                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1125
1126       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1127       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1128       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1129       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1130       if (!isOk)
1131       {
1132         theDI << "Fail: view dump failed!\n";
1133         return 0;
1134       }
1135       break;
1136     }
1137     case ViewerTest_SP_OverUnder:
1138     {
1139       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1140       {
1141         theDI << "Fail: not enough memory for image allocation!\n";
1142         return 0;
1143       }
1144
1145       Image_PixMap aPixMapL, aPixMapR;
1146       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1147                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1148       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1149                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1150
1151       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1152       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1153       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1154       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1155       if (!isOk)
1156       {
1157         theDI << "Fail: view dump failed!\n";
1158         return 0;
1159       }
1160       break;
1161     }
1162   }
1163
1164   if (!aPixMap.Save (aFilePath))
1165   {
1166     theDI << "Fail: image can not be saved!\n";
1167   }
1168   return 0;
1169 }
1170
1171 enum TypeOfDispOperation
1172 {
1173   TypeOfDispOperation_SetDispMode,
1174   TypeOfDispOperation_UnsetDispMode
1175 };
1176
1177 //! Displays,Erase...
1178 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1179                                                 const Standard_Integer theMode,
1180                                                 const TypeOfDispOperation theType,
1181                                                 const Standard_Boolean theToUpdate)
1182 {
1183   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1184   switch (theType)
1185   {
1186     case TypeOfDispOperation_SetDispMode:
1187     {
1188       if (!thePrs.IsNull())
1189       {
1190         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1191       }
1192       else
1193       {
1194         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1195       }
1196       break;
1197     }
1198     case TypeOfDispOperation_UnsetDispMode:
1199     {
1200       if (!thePrs.IsNull())
1201       {
1202         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1203       }
1204       else
1205       {
1206         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1207       }
1208       break;
1209     }
1210   }
1211 }
1212
1213 //=======================================================================
1214 //function :
1215 //purpose  :
1216 //=======================================================================
1217 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1218 {
1219   if (argc < 1
1220    || argc > 3)
1221   {
1222     std::cout << "Syntax error: wrong number of arguments\n";
1223     return 1;
1224   }
1225
1226   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1227                             ? TypeOfDispOperation_UnsetDispMode
1228                             : TypeOfDispOperation_SetDispMode;
1229   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1230   if (aType == TypeOfDispOperation_UnsetDispMode)
1231   {
1232     if (argc == 1)
1233     {
1234       if (aCtx->NbSelected() == 0)
1235       {
1236         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1237       }
1238       else
1239       {
1240         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1241         {
1242           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1243         }
1244       }
1245       aCtx->UpdateCurrentViewer();
1246     }
1247     else
1248     {
1249       TCollection_AsciiString aName = argv[1];
1250       Handle(AIS_InteractiveObject) aPrs;
1251       if (GetMapOfAIS().Find2 (aName, aPrs)
1252       && !aPrs.IsNull())
1253       {
1254         VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1255       }
1256     }
1257   }
1258   else if (argc == 2)
1259   {
1260     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1261     if (aCtx->NbSelected() == 0
1262      && aType == TypeOfDispOperation_SetDispMode)
1263     {
1264       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1265     }
1266     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1267     {
1268       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1269     }
1270     aCtx->UpdateCurrentViewer();
1271   }
1272   else
1273   {
1274     Handle(AIS_InteractiveObject) aPrs;
1275     TCollection_AsciiString aName (argv[1]);
1276     if (GetMapOfAIS().Find2 (aName, aPrs)
1277      && !aPrs.IsNull())
1278     {
1279       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1280     }
1281   }
1282   return 0;
1283 }
1284
1285
1286 //=======================================================================
1287 //function :
1288 //purpose  :
1289 //=======================================================================
1290 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1291 {
1292   if(argc==1) return 1;
1293   Standard_Integer On = Draw::Atoi(argv[1]);
1294   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1295
1296   if(argc==2)
1297   {
1298     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1299     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1300     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1301     {
1302       if(On==1)
1303       {
1304         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1305       }
1306       else
1307       {
1308         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1309       }
1310     }
1311
1312     Ctx->UpdateCurrentViewer();
1313   }
1314   else {
1315     Handle(AIS_InteractiveObject) IO;
1316     TCollection_AsciiString name = argv[2];
1317     if (GetMapOfAIS().Find2 (name, IO)
1318     && !IO.IsNull())
1319     {
1320       if(On==1)
1321         Ctx->SubIntensityOn(IO, Standard_True);
1322       else
1323         Ctx->SubIntensityOff(IO, Standard_True);
1324     }
1325     else return 1;
1326   }
1327   return 0;
1328 }
1329
1330 //! Auxiliary class to iterate presentations from different collections.
1331 class ViewTest_PrsIter
1332 {
1333 public:
1334
1335   //! Create and initialize iterator object.
1336   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1337   : mySource (IterSource_All)
1338   {
1339     NCollection_Sequence<TCollection_AsciiString> aNames;
1340     if (!theName.IsEmpty())
1341     aNames.Append (theName);
1342     Init (aNames);
1343   }
1344
1345   //! Create and initialize iterator object.
1346   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1347   : mySource (IterSource_All)
1348   {
1349     Init (theNames);
1350   }
1351
1352   //! Initialize the iterator.
1353   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1354   {
1355     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1356     mySeq = theNames;
1357     mySelIter.Nullify();
1358     myCurrent.Nullify();
1359     myCurrentTrs.Nullify();
1360     if (!mySeq.IsEmpty())
1361     {
1362       mySource = IterSource_List;
1363       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1364     }
1365     else if (aCtx->NbSelected() > 0)
1366     {
1367       mySource  = IterSource_Selected;
1368       mySelIter = aCtx;
1369       mySelIter->InitSelected();
1370     }
1371     else
1372     {
1373       mySource = IterSource_All;
1374       myMapIter.Initialize (GetMapOfAIS());
1375     }
1376     initCurrent();
1377   }
1378
1379   const TCollection_AsciiString& CurrentName() const
1380   {
1381     return myCurrentName;
1382   }
1383
1384   const Handle(AIS_InteractiveObject)& Current() const
1385   {
1386     return myCurrent;
1387   }
1388
1389   const Handle(Standard_Transient)& CurrentTrs() const
1390   {
1391     return myCurrentTrs;
1392   }
1393
1394   //! @return true if iterator points to valid object within collection
1395   Standard_Boolean More() const
1396   {
1397     switch (mySource)
1398     {
1399       case IterSource_All:      return myMapIter.More();
1400       case IterSource_List:     return mySeqIter.More();
1401       case IterSource_Selected: return mySelIter->MoreSelected();
1402     }
1403     return Standard_False;
1404   }
1405
1406   //! Go to the next item.
1407   void Next()
1408   {
1409     myCurrentName.Clear();
1410     myCurrentTrs.Nullify();
1411     myCurrent.Nullify();
1412     switch (mySource)
1413     {
1414       case IterSource_All:
1415       {
1416         myMapIter.Next();
1417         break;
1418       }
1419       case IterSource_List:
1420       {
1421         mySeqIter.Next();
1422         break;
1423       }
1424       case IterSource_Selected:
1425       {
1426         mySelIter->NextSelected();
1427         break;
1428       }
1429     }
1430     initCurrent();
1431   }
1432
1433 private:
1434
1435   void initCurrent()
1436   {
1437     switch (mySource)
1438     {
1439       case IterSource_All:
1440       {
1441         if (myMapIter.More())
1442         {
1443           myCurrentName = myMapIter.Key2();
1444           myCurrentTrs  = myMapIter.Key1();
1445           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1446         }
1447         break;
1448       }
1449       case IterSource_List:
1450       {
1451         if (mySeqIter.More())
1452         {
1453           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1454           {
1455             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1456             return;
1457           }
1458           myCurrentName = mySeqIter.Value();
1459           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1460           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1461         }
1462         break;
1463       }
1464       case IterSource_Selected:
1465       {
1466         if (mySelIter->MoreSelected())
1467         {
1468           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1469           myCurrent     = mySelIter->SelectedInteractive();
1470         }
1471         break;
1472       }
1473     }
1474   }
1475
1476 private:
1477
1478   enum IterSource
1479   {
1480     IterSource_All,
1481     IterSource_List,
1482     IterSource_Selected
1483   };
1484
1485 private:
1486
1487   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1488   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1489   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1490   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1491
1492   TCollection_AsciiString        myCurrentName;//!< current item name
1493   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1494   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1495
1496   IterSource                     mySource;     //!< iterated collection
1497
1498 };
1499
1500 //==============================================================================
1501 //function : VInteriorStyle
1502 //purpose  : sets interior style of the a selected or named or displayed shape
1503 //==============================================================================
1504 static int VSetInteriorStyle (Draw_Interpretor& theDI,
1505                               Standard_Integer  theArgNb,
1506                               const char**      theArgVec)
1507 {
1508   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1509   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1510   if (aCtx.IsNull())
1511   {
1512     std::cerr << "Error: no active view!\n";
1513     return 1;
1514   }
1515
1516   Standard_Integer anArgIter = 1;
1517   for (; anArgIter < theArgNb; ++anArgIter)
1518   {
1519     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
1520     {
1521       break;
1522     }
1523   }
1524   TCollection_AsciiString aName;
1525   if (theArgNb - anArgIter == 2)
1526   {
1527     aName = theArgVec[anArgIter++];
1528   }
1529   else if (theArgNb - anArgIter != 1)
1530   {
1531     std::cout << "Error: wrong number of arguments! See usage:\n";
1532     theDI.PrintHelp (theArgVec[0]);
1533     return 1;
1534   }
1535   Aspect_InteriorStyle    anInterStyle = Aspect_IS_SOLID;
1536   TCollection_AsciiString aStyleArg (theArgVec[anArgIter++]);
1537   aStyleArg.LowerCase();
1538   if (aStyleArg == "empty")
1539   {
1540     anInterStyle = Aspect_IS_EMPTY;
1541   }
1542   else if (aStyleArg == "hollow")
1543   {
1544     anInterStyle = Aspect_IS_HOLLOW;
1545   }
1546   else if (aStyleArg == "hatch")
1547   {
1548     anInterStyle = Aspect_IS_HATCH;
1549   }
1550   else if (aStyleArg == "solid")
1551   {
1552     anInterStyle = Aspect_IS_SOLID;
1553   }
1554   else if (aStyleArg == "hiddenline")
1555   {
1556     anInterStyle = Aspect_IS_HIDDENLINE;
1557   }
1558   else if (aStyleArg == "point")
1559   {
1560     anInterStyle = Aspect_IS_POINT;
1561   }
1562   else
1563   {
1564     const Standard_Integer anIntStyle = aStyleArg.IntegerValue();
1565     if (anIntStyle < Aspect_IS_EMPTY
1566      || anIntStyle > Aspect_IS_POINT)
1567     {
1568       std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
1569                 << Aspect_IS_POINT << " (Aspect_IS_POINT)]\n";
1570       return 1;
1571     }
1572     anInterStyle = (Aspect_InteriorStyle )anIntStyle;
1573   }
1574
1575   if (!aName.IsEmpty()
1576    && !GetMapOfAIS().IsBound2 (aName))
1577   {
1578     std::cout << "Error: object " << aName << " is not displayed!\n";
1579     return 1;
1580   }
1581
1582   for (ViewTest_PrsIter anIter (aName); anIter.More(); anIter.Next())
1583   {
1584     const Handle(AIS_InteractiveObject)& anIO = anIter.Current();
1585     if (!anIO.IsNull())
1586     {
1587       const Handle(Prs3d_Drawer)& aDrawer        = anIO->Attributes();
1588       Handle(Prs3d_ShadingAspect) aShadingAspect = aDrawer->ShadingAspect();
1589       Handle(Graphic3d_AspectFillArea3d) aFillAspect = aShadingAspect->Aspect();
1590       aFillAspect->SetInteriorStyle (anInterStyle);
1591       if (anInterStyle == Aspect_IS_HATCH
1592        && aFillAspect->HatchStyle().IsNull())
1593       {
1594         aFillAspect->SetHatchStyle (Aspect_HS_VERTICAL);
1595       }
1596       aCtx->RecomputePrsOnly (anIO, Standard_False, Standard_True);
1597     }
1598   }
1599   return 0;
1600 }
1601
1602 //! Auxiliary structure for VAspects
1603 struct ViewerTest_AspectsChangeSet
1604 {
1605   Standard_Integer             ToSetVisibility;
1606   Standard_Integer             Visibility;
1607
1608   Standard_Integer             ToSetColor;
1609   Quantity_Color               Color;
1610
1611   Standard_Integer             ToSetLineWidth;
1612   Standard_Real                LineWidth;
1613
1614   Standard_Integer             ToSetTypeOfLine;
1615   Aspect_TypeOfLine            TypeOfLine;
1616
1617   Standard_Integer             ToSetTypeOfMarker;
1618   Aspect_TypeOfMarker          TypeOfMarker;
1619   Handle(Image_PixMap)         MarkerImage;
1620
1621   Standard_Integer             ToSetMarkerSize;
1622   Standard_Real                MarkerSize;
1623
1624   Standard_Integer             ToSetTransparency;
1625   Standard_Real                Transparency;
1626
1627   Standard_Integer             ToSetAlphaMode;
1628   Graphic3d_AlphaMode          AlphaMode;
1629   Standard_ShortReal           AlphaCutoff;
1630
1631   Standard_Integer             ToSetMaterial;
1632   Graphic3d_NameOfMaterial     Material;
1633   TCollection_AsciiString      MatName;
1634
1635   NCollection_Sequence<TopoDS_Shape> SubShapes;
1636
1637   Standard_Integer             ToSetShowFreeBoundary;
1638   Standard_Integer             ToSetFreeBoundaryWidth;
1639   Standard_Real                FreeBoundaryWidth;
1640   Standard_Integer             ToSetFreeBoundaryColor;
1641   Quantity_Color               FreeBoundaryColor;
1642
1643   Standard_Integer             ToEnableIsoOnTriangulation;
1644
1645   Standard_Integer             ToSetMaxParamValue;
1646   Standard_Real                MaxParamValue;
1647
1648   Standard_Integer             ToSetSensitivity;
1649   Standard_Integer             SelectionMode;
1650   Standard_Integer             Sensitivity;
1651
1652   Standard_Integer             ToSetHatch;
1653   Standard_Integer             StdHatchStyle;
1654   TCollection_AsciiString      PathToHatchPattern;
1655
1656   Standard_Integer             ToSetShadingModel;
1657   Graphic3d_TypeOfShadingModel ShadingModel;
1658   TCollection_AsciiString      ShadingModelName;
1659
1660   //! Empty constructor
1661   ViewerTest_AspectsChangeSet()
1662   : ToSetVisibility   (0),
1663     Visibility        (1),
1664     ToSetColor        (0),
1665     Color             (DEFAULT_COLOR),
1666     ToSetLineWidth    (0),
1667     LineWidth         (1.0),
1668     ToSetTypeOfLine   (0),
1669     TypeOfLine        (Aspect_TOL_SOLID),
1670     ToSetTypeOfMarker (0),
1671     TypeOfMarker      (Aspect_TOM_PLUS),
1672     ToSetMarkerSize   (0),
1673     MarkerSize        (1.0),
1674     ToSetTransparency (0),
1675     Transparency      (0.0),
1676     ToSetAlphaMode    (0),
1677     AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
1678     AlphaCutoff       (0.5f),
1679     ToSetMaterial     (0),
1680     Material          (Graphic3d_NOM_DEFAULT),
1681     ToSetShowFreeBoundary      (0),
1682     ToSetFreeBoundaryWidth     (0),
1683     FreeBoundaryWidth          (1.0),
1684     ToSetFreeBoundaryColor     (0),
1685     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1686     ToEnableIsoOnTriangulation (-1),
1687     ToSetMaxParamValue         (0),
1688     MaxParamValue              (500000),
1689     ToSetSensitivity           (0),
1690     SelectionMode              (-1),
1691     Sensitivity                (-1),
1692     ToSetHatch                 (0),
1693     StdHatchStyle              (-1),
1694     ToSetShadingModel          (0),
1695     ShadingModel               (Graphic3d_TOSM_DEFAULT)
1696     {}
1697
1698   //! @return true if no changes have been requested
1699   Standard_Boolean IsEmpty() const
1700   {
1701     return ToSetVisibility        == 0
1702         && ToSetLineWidth         == 0
1703         && ToSetTransparency      == 0
1704         && ToSetAlphaMode         == 0
1705         && ToSetColor             == 0
1706         && ToSetMaterial          == 0
1707         && ToSetShowFreeBoundary  == 0
1708         && ToSetFreeBoundaryColor == 0
1709         && ToSetFreeBoundaryWidth == 0
1710         && ToSetMaxParamValue     == 0
1711         && ToSetSensitivity       == 0
1712         && ToSetHatch             == 0
1713         && ToSetShadingModel      == 0;
1714   }
1715
1716   //! @return true if properties are valid
1717   Standard_Boolean Validate (const Standard_Boolean theIsSubPart) const
1718   {
1719     Standard_Boolean isOk = Standard_True;
1720     if (Visibility != 0 && Visibility != 1)
1721     {
1722       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1723       isOk = Standard_False;
1724     }
1725     if (LineWidth <= 0.0
1726      || LineWidth >  10.0)
1727     {
1728       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1729       isOk = Standard_False;
1730     }
1731     if (Transparency < 0.0
1732      || Transparency > 1.0)
1733     {
1734       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1735       isOk = Standard_False;
1736     }
1737     if (theIsSubPart
1738      && ToSetTransparency != 0)
1739     {
1740       std::cout << "Error: the transparency can not be defined for sub-part of object!\n";
1741       isOk = Standard_False;
1742     }
1743     if (ToSetAlphaMode == 1
1744      && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
1745     {
1746       std::cout << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")\n";
1747       isOk = Standard_False;
1748     }
1749     if (ToSetMaterial == 1
1750      && Material == Graphic3d_NOM_DEFAULT)
1751     {
1752       std::cout << "Error: unknown material " << MatName << ".\n";
1753       isOk = Standard_False;
1754     }
1755     if (FreeBoundaryWidth <= 0.0
1756      || FreeBoundaryWidth >  10.0)
1757     {
1758       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1759       isOk = Standard_False;
1760     }
1761     if (MaxParamValue < 0.0)
1762     {
1763       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1764       isOk = Standard_False;
1765     }
1766     if (Sensitivity <= 0 && ToSetSensitivity)
1767     {
1768       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1769       isOk = Standard_False;
1770     }
1771     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1772     {
1773       std::cout << "Error: hatch style must be specified\n";
1774       isOk = Standard_False;
1775     }
1776     if (ToSetShadingModel == 1
1777     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_FRAGMENT))
1778     {
1779       std::cout << "Error: unknown shading model " << ShadingModelName << ".\n";
1780       isOk = Standard_False;
1781     }
1782     return isOk;
1783   }
1784
1785 };
1786
1787 //==============================================================================
1788 //function : VAspects
1789 //purpose  :
1790 //==============================================================================
1791 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
1792                                   Standard_Integer  theArgNb,
1793                                   const char**      theArgVec)
1794 {
1795   TCollection_AsciiString aCmdName (theArgVec[0]);
1796   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1797   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1798   if (aCtx.IsNull())
1799   {
1800     std::cerr << "Error: no active view!\n";
1801     return 1;
1802   }
1803
1804   Standard_Integer anArgIter = 1;
1805   Standard_Boolean isDefaults = Standard_False;
1806   NCollection_Sequence<TCollection_AsciiString> aNames;
1807   for (; anArgIter < theArgNb; ++anArgIter)
1808   {
1809     TCollection_AsciiString anArg = theArgVec[anArgIter];
1810     if (anUpdateTool.parseRedrawMode (anArg))
1811     {
1812       continue;
1813     }
1814     else if (!anArg.IsEmpty()
1815            && anArg.Value (1) != '-')
1816     {
1817       aNames.Append (anArg);
1818     }
1819     else
1820     {
1821       if (anArg == "-defaults")
1822       {
1823         isDefaults = Standard_True;
1824         ++anArgIter;
1825       }
1826       break;
1827     }
1828   }
1829
1830   if (!aNames.IsEmpty() && isDefaults)
1831   {
1832     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
1833     return 1;
1834   }
1835
1836   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
1837   aChanges.Append (ViewerTest_AspectsChangeSet());
1838   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
1839
1840   // parse syntax of legacy commands
1841   if (aCmdName == "vsetwidth")
1842   {
1843     if (aNames.IsEmpty()
1844     || !aNames.Last().IsRealValue())
1845     {
1846       std::cout << "Error: not enough arguments!\n";
1847       return 1;
1848     }
1849     aChangeSet->ToSetLineWidth = 1;
1850     aChangeSet->LineWidth = aNames.Last().RealValue();
1851     aNames.Remove (aNames.Length());
1852   }
1853   else if (aCmdName == "vunsetwidth")
1854   {
1855     aChangeSet->ToSetLineWidth = -1;
1856   }
1857   else if (aCmdName == "vsetcolor")
1858   {
1859     if (aNames.IsEmpty())
1860     {
1861       std::cout << "Error: not enough arguments!\n";
1862       return 1;
1863     }
1864     aChangeSet->ToSetColor = 1;
1865
1866     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
1867     Standard_Boolean     isOk   = Standard_False;
1868     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
1869     {
1870       aChangeSet->Color = aColor;
1871       aNames.Remove (aNames.Length());
1872       isOk = Standard_True;
1873     }
1874     else if (aNames.Length() >= 3)
1875     {
1876       const TCollection_AsciiString anRgbStr[3] =
1877       {
1878         aNames.Value (aNames.Upper() - 2),
1879         aNames.Value (aNames.Upper() - 1),
1880         aNames.Value (aNames.Upper() - 0)
1881       };
1882       isOk = anRgbStr[0].IsRealValue()
1883           && anRgbStr[1].IsRealValue()
1884           && anRgbStr[2].IsRealValue();
1885       if (isOk)
1886       {
1887         Graphic3d_Vec4d anRgb;
1888         anRgb.x() = anRgbStr[0].RealValue();
1889         anRgb.y() = anRgbStr[1].RealValue();
1890         anRgb.z() = anRgbStr[2].RealValue();
1891         if (anRgb.x() < 0.0 || anRgb.x() > 1.0
1892          || anRgb.y() < 0.0 || anRgb.y() > 1.0
1893          || anRgb.z() < 0.0 || anRgb.z() > 1.0)
1894         {
1895           std::cout << "Error: RGB color values should be within range 0..1!\n";
1896           return 1;
1897         }
1898         aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
1899         aNames.Remove (aNames.Length());
1900         aNames.Remove (aNames.Length());
1901         aNames.Remove (aNames.Length());
1902       }
1903     }
1904     if (!isOk)
1905     {
1906       std::cout << "Error: not enough arguments!\n";
1907       return 1;
1908     }
1909   }
1910   else if (aCmdName == "vunsetcolor")
1911   {
1912     aChangeSet->ToSetColor = -1;
1913   }
1914   else if (aCmdName == "vsettransparency")
1915   {
1916     if (aNames.IsEmpty()
1917     || !aNames.Last().IsRealValue())
1918     {
1919       std::cout << "Error: not enough arguments!\n";
1920       return 1;
1921     }
1922     aChangeSet->ToSetTransparency = 1;
1923     aChangeSet->Transparency  = aNames.Last().RealValue();
1924     aNames.Remove (aNames.Length());
1925   }
1926   else if (aCmdName == "vunsettransparency")
1927   {
1928     aChangeSet->ToSetTransparency = -1;
1929   }
1930   else if (aCmdName == "vsetmaterial")
1931   {
1932     if (aNames.IsEmpty())
1933     {
1934       std::cout << "Error: not enough arguments!\n";
1935       return 1;
1936     }
1937     aChangeSet->ToSetMaterial = 1;
1938     aChangeSet->MatName  = aNames.Last();
1939     aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1940     aNames.Remove (aNames.Length());
1941   }
1942   else if (aCmdName == "vunsetmaterial")
1943   {
1944     aChangeSet->ToSetMaterial = -1;
1945   }
1946   else if (anArgIter >= theArgNb)
1947   {
1948     std::cout << "Error: not enough arguments!\n";
1949     return 1;
1950   }
1951
1952   if (!aChangeSet->IsEmpty())
1953   {
1954     anArgIter = theArgNb;
1955   }
1956   for (; anArgIter < theArgNb; ++anArgIter)
1957   {
1958     TCollection_AsciiString anArg = theArgVec[anArgIter];
1959     anArg.LowerCase();
1960     if (anArg == "-setwidth"
1961      || anArg == "-setlinewidth")
1962     {
1963       if (++anArgIter >= theArgNb)
1964       {
1965         std::cout << "Error: wrong syntax at " << anArg << "\n";
1966         return 1;
1967       }
1968       aChangeSet->ToSetLineWidth = 1;
1969       aChangeSet->LineWidth = Draw::Atof (theArgVec[anArgIter]);
1970     }
1971     else if (anArg == "-unsetwidth"
1972           || anArg == "-unsetlinewidth")
1973     {
1974       aChangeSet->ToSetLineWidth = -1;
1975       aChangeSet->LineWidth = 1.0;
1976     }
1977     else if (anArg == "-settransp"
1978           || anArg == "-settransparency")
1979     {
1980       if (++anArgIter >= theArgNb)
1981       {
1982         std::cout << "Error: wrong syntax at " << anArg << "\n";
1983         return 1;
1984       }
1985       aChangeSet->ToSetTransparency = 1;
1986       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
1987       if (aChangeSet->Transparency >= 0.0
1988        && aChangeSet->Transparency <= Precision::Confusion())
1989       {
1990         aChangeSet->ToSetTransparency = -1;
1991         aChangeSet->Transparency = 0.0;
1992       }
1993     }
1994     else if (anArg == "-setalphamode")
1995     {
1996       if (++anArgIter >= theArgNb)
1997       {
1998         std::cout << "Error: wrong syntax at " << anArg << "\n";
1999         return 1;
2000       }
2001       aChangeSet->ToSetAlphaMode = 1;
2002       aChangeSet->AlphaCutoff = 0.5f;
2003       {
2004         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2005         aParam.LowerCase();
2006         if (aParam == "opaque")
2007         {
2008           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2009         }
2010         else if (aParam == "mask")
2011         {
2012           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2013         }
2014         else if (aParam == "blend")
2015         {
2016           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2017         }
2018         else if (aParam == "blendauto"
2019               || aParam == "auto")
2020         {
2021           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2022         }
2023         else
2024         {
2025           std::cout << "Error: wrong syntax at " << aParam << "\n";
2026           return 1;
2027         }
2028       }
2029
2030       if (anArgIter + 1 < theArgNb
2031        && theArgVec[anArgIter + 1][0] != '-')
2032       {
2033         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2034         if (aParam2.IsRealValue())
2035         {
2036           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2037           ++anArgIter;
2038         }
2039       }
2040     }
2041     else if (anArg == "-setvis"
2042           || anArg == "-setvisibility")
2043     {
2044       if (++anArgIter >= theArgNb)
2045       {
2046         std::cout << "Error: wrong syntax at " << anArg << "\n";
2047         return 1;
2048       }
2049
2050       aChangeSet->ToSetVisibility = 1;
2051       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2052     }
2053     else if (anArg == "-setalpha")
2054     {
2055       if (++anArgIter >= theArgNb)
2056       {
2057         std::cout << "Error: wrong syntax at " << anArg << "\n";
2058         return 1;
2059       }
2060       aChangeSet->ToSetTransparency = 1;
2061       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2062       if (aChangeSet->Transparency < 0.0
2063        || aChangeSet->Transparency > 1.0)
2064       {
2065         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
2066         return 1;
2067       }
2068       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2069       if (aChangeSet->Transparency >= 0.0
2070        && aChangeSet->Transparency <= Precision::Confusion())
2071       {
2072         aChangeSet->ToSetTransparency = -1;
2073         aChangeSet->Transparency = 0.0;
2074       }
2075     }
2076     else if (anArg == "-unsettransp"
2077           || anArg == "-unsettransparency"
2078           || anArg == "-unsetalpha"
2079           || anArg == "-opaque")
2080     {
2081       aChangeSet->ToSetTransparency = -1;
2082       aChangeSet->Transparency = 0.0;
2083     }
2084     else if (anArg == "-setcolor")
2085     {
2086       Standard_Integer aNbComps  = 0;
2087       Standard_Integer aCompIter = anArgIter + 1;
2088       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
2089       {
2090         if (theArgVec[aCompIter][0] == '-')
2091         {
2092           break;
2093         }
2094       }
2095       switch (aNbComps)
2096       {
2097         case 1:
2098         {
2099           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2100           Standard_CString     aName  = theArgVec[anArgIter + 1];
2101           if (!Quantity_Color::ColorFromName (aName, aColor))
2102           {
2103             std::cout << "Error: unknown color name '" << aName << "'\n";
2104             return 1;
2105           }
2106           aChangeSet->Color = aColor;
2107           break;
2108         }
2109         case 3:
2110         {
2111           Graphic3d_Vec3d anRgb;
2112           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
2113           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
2114           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
2115           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
2116            || anRgb.y() < 0.0 || anRgb.y() > 1.0
2117            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
2118           {
2119             std::cout << "Error: RGB color values should be within range 0..1!\n";
2120             return 1;
2121           }
2122           aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
2123           break;
2124         }
2125         default:
2126         {
2127           std::cout << "Error: wrong syntax at " << anArg << "\n";
2128           return 1;
2129         }
2130       }
2131       aChangeSet->ToSetColor = 1;
2132       anArgIter += aNbComps;
2133     }
2134     else if (anArg == "-setlinetype")
2135     {
2136       if (++anArgIter >= theArgNb)
2137       {
2138         std::cout << "Error: wrong syntax at " << anArg << "\n";
2139         return 1;
2140       }
2141       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aChangeSet->TypeOfLine))
2142       {
2143         std::cout << "Error: wrong syntax at " << anArg << "\n";
2144         return 1;
2145       }
2146
2147       aChangeSet->ToSetTypeOfLine = 1;
2148     }
2149     else if (anArg == "-unsetlinetype")
2150     {
2151       aChangeSet->ToSetTypeOfLine = -1;
2152     }
2153     else if (anArg == "-setmarkertype"
2154           || anArg == "-setpointtype")
2155     {
2156       if (++anArgIter >= theArgNb)
2157       {
2158         std::cout << "Error: wrong syntax at " << anArg << "\n";
2159         return 1;
2160       }
2161       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2162       {
2163         std::cout << "Error: wrong syntax at " << anArg << "\n";
2164         return 1;
2165       }
2166
2167       aChangeSet->ToSetTypeOfMarker = 1;
2168     }
2169     else if (anArg == "-unsetmarkertype"
2170           || anArg == "-unsetpointtype")
2171     {
2172       aChangeSet->ToSetTypeOfMarker = -1;
2173     }
2174     else if (anArg == "-setmarkersize"
2175           || anArg == "-setpointsize")
2176     {
2177       if (++anArgIter >= theArgNb)
2178       {
2179         std::cout << "Error: wrong syntax at " << anArg << "\n";
2180         return 1;
2181       }
2182       aChangeSet->ToSetMarkerSize = 1;
2183       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2184     }
2185     else if (anArg == "-unsetmarkersize"
2186           || anArg == "-unsetpointsize")
2187     {
2188       aChangeSet->ToSetMarkerSize = -1;
2189       aChangeSet->MarkerSize = 1.0;
2190     }
2191     else if (anArg == "-unsetcolor")
2192     {
2193       aChangeSet->ToSetColor = -1;
2194       aChangeSet->Color = DEFAULT_COLOR;
2195     }
2196     else if (anArg == "-setmat"
2197           || anArg == "-setmaterial")
2198     {
2199       if (++anArgIter >= theArgNb)
2200       {
2201         std::cout << "Error: wrong syntax at " << anArg << "\n";
2202         return 1;
2203       }
2204       aChangeSet->ToSetMaterial = 1;
2205       aChangeSet->MatName  = theArgVec[anArgIter];
2206       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
2207     }
2208     else if (anArg == "-unsetmat"
2209           || anArg == "-unsetmaterial")
2210     {
2211       aChangeSet->ToSetMaterial = -1;
2212       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2213     }
2214     else if (anArg == "-subshape"
2215           || anArg == "-subshapes")
2216     {
2217       if (isDefaults)
2218       {
2219         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
2220         return 1;
2221       }
2222
2223       if (aNames.IsEmpty())
2224       {
2225         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
2226         return 1;
2227       }
2228
2229       aChanges.Append (ViewerTest_AspectsChangeSet());
2230       aChangeSet = &aChanges.ChangeLast();
2231
2232       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2233       {
2234         Standard_CString aSubShapeName = theArgVec[anArgIter];
2235         if (*aSubShapeName == '-')
2236         {
2237           --anArgIter;
2238           break;
2239         }
2240
2241         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2242         if (aSubShape.IsNull())
2243         {
2244           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
2245           return 1;
2246         }
2247         aChangeSet->SubShapes.Append (aSubShape);
2248       }
2249
2250       if (aChangeSet->SubShapes.IsEmpty())
2251       {
2252         std::cerr << "Error: empty list is specified after -subshapes!\n";
2253         return 1;
2254       }
2255     }
2256     else if (anArg == "-freeboundary"
2257           || anArg == "-fb")
2258     {
2259       if (++anArgIter >= theArgNb)
2260       {
2261         std::cout << "Error: wrong syntax at " << anArg << "\n";
2262         return 1;
2263       }
2264       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2265       aValue.LowerCase();
2266       if (aValue == "on"
2267        || aValue == "1")
2268       {
2269         aChangeSet->ToSetShowFreeBoundary = 1;
2270       }
2271       else if (aValue == "off"
2272             || aValue == "0")
2273       {
2274         aChangeSet->ToSetShowFreeBoundary = -1;
2275       }
2276       else
2277       {
2278         std::cout << "Error: wrong syntax at " << anArg << "\n";
2279         return 1;
2280       }
2281     }
2282     else if (anArg == "-setfreeboundarywidth"
2283           || anArg == "-setfbwidth")
2284     {
2285       if (++anArgIter >= theArgNb)
2286       {
2287         std::cout << "Error: wrong syntax at " << anArg << "\n";
2288         return 1;
2289       }
2290       aChangeSet->ToSetFreeBoundaryWidth = 1;
2291       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2292     }
2293     else if (anArg == "-unsetfreeboundarywidth"
2294           || anArg == "-unsetfbwidth")
2295     {
2296       aChangeSet->ToSetFreeBoundaryWidth = -1;
2297       aChangeSet->FreeBoundaryWidth = 1.0;
2298     }
2299     else if (anArg == "-setfreeboundarycolor"
2300           || anArg == "-setfbcolor")
2301     {
2302       Standard_Integer aNbComps  = 0;
2303       Standard_Integer aCompIter = anArgIter + 1;
2304       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
2305       {
2306         if (theArgVec[aCompIter][0] == '-')
2307         {
2308           break;
2309         }
2310       }
2311       switch (aNbComps)
2312       {
2313         case 1:
2314         {
2315           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2316           Standard_CString     aName  = theArgVec[anArgIter + 1];
2317           if (!Quantity_Color::ColorFromName (aName, aColor))
2318           {
2319             std::cout << "Error: unknown free boundary color name '" << aName << "'\n";
2320             return 1;
2321           }
2322           aChangeSet->FreeBoundaryColor = aColor;
2323           break;
2324         }
2325         case 3:
2326         {
2327           Graphic3d_Vec3d anRgb;
2328           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
2329           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
2330           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
2331           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
2332            || anRgb.y() < 0.0 || anRgb.y() > 1.0
2333            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
2334           {
2335             std::cout << "Error: free boundary RGB color values should be within range 0..1!\n";
2336             return 1;
2337           }
2338           aChangeSet->FreeBoundaryColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
2339           break;
2340         }
2341         default:
2342         {
2343           std::cout << "Error: wrong syntax at " << anArg << "\n";
2344           return 1;
2345         }
2346       }
2347       aChangeSet->ToSetFreeBoundaryColor = 1;
2348       anArgIter += aNbComps;
2349     }
2350     else if (anArg == "-unsetfreeboundarycolor"
2351           || anArg == "-unsetfbcolor")
2352     {
2353       aChangeSet->ToSetFreeBoundaryColor = -1;
2354       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2355     }
2356     else if (anArg == "-unset")
2357     {
2358       aChangeSet->ToSetVisibility = 1;
2359       aChangeSet->Visibility = 1;
2360       aChangeSet->ToSetLineWidth = -1;
2361       aChangeSet->LineWidth = 1.0;
2362       aChangeSet->ToSetTypeOfLine = -1;
2363       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
2364       aChangeSet->ToSetTypeOfMarker = -1;
2365       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
2366       aChangeSet->ToSetMarkerSize = -1;
2367       aChangeSet->MarkerSize = 1.0;
2368       aChangeSet->ToSetTransparency = -1;
2369       aChangeSet->Transparency = 0.0;
2370       aChangeSet->ToSetAlphaMode = -1;
2371       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2372       aChangeSet->AlphaCutoff = 0.5f;
2373       aChangeSet->ToSetColor = -1;
2374       aChangeSet->Color = DEFAULT_COLOR;
2375       aChangeSet->ToSetMaterial = -1;
2376       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2377       aChangeSet->ToSetShowFreeBoundary = -1;
2378       aChangeSet->ToSetFreeBoundaryColor = -1;
2379       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2380       aChangeSet->ToSetFreeBoundaryWidth = -1;
2381       aChangeSet->FreeBoundaryWidth = 1.0;
2382       aChangeSet->ToSetHatch = -1;
2383       aChangeSet->StdHatchStyle = -1;
2384       aChangeSet->PathToHatchPattern.Clear();
2385       aChangeSet->ToSetShadingModel = -1;
2386       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
2387     }
2388     else if (anArg == "-isoontriangulation"
2389           || anArg == "-isoontriang")
2390     {
2391       if (++anArgIter >= theArgNb)
2392       {
2393         std::cout << "Error: wrong syntax at " << anArg << "\n";
2394         return 1;
2395       }
2396       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2397       aValue.LowerCase();
2398       if (aValue == "on"
2399         || aValue == "1")
2400       {
2401         aChangeSet->ToEnableIsoOnTriangulation = 1;
2402       }
2403       else if (aValue == "off"
2404         || aValue == "0")
2405       {
2406         aChangeSet->ToEnableIsoOnTriangulation = 0;
2407       }
2408       else
2409       {
2410         std::cout << "Error: wrong syntax at " << anArg << "\n";
2411         return 1;
2412       }
2413     }
2414     else if (anArg == "-setmaxparamvalue")
2415     {
2416       if (++anArgIter >= theArgNb)
2417       {
2418         std::cout << "Error: wrong syntax at " << anArg << "\n";
2419         return 1;
2420       }
2421       aChangeSet->ToSetMaxParamValue = 1;
2422       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
2423     }
2424     else if (anArg == "-setsensitivity")
2425     {
2426       if (isDefaults)
2427       {
2428         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
2429         return 1;
2430       }
2431
2432       if (aNames.IsEmpty())
2433       {
2434         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
2435         return 1;
2436       }
2437
2438       if (anArgIter + 2 >= theArgNb)
2439       {
2440         std::cout << "Error: wrong syntax at " << anArg << "\n";
2441         return 1;
2442       }
2443       aChangeSet->ToSetSensitivity = 1;
2444       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
2445       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
2446     }
2447     else if (anArg == "-sethatch")
2448     {
2449       if (isDefaults)
2450       {
2451         std::cout << "Error: wrong syntax. -setHatch can not be used together with -defaults call!\n";
2452         return 1;
2453       }
2454
2455       if (aNames.IsEmpty())
2456       {
2457         std::cout << "Error: object should be specified explicitly when -setHatch is used!\n";
2458         return 1;
2459       }
2460
2461       aChangeSet->ToSetHatch = 1;
2462       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
2463       if (anArgHatch.Length() <= 2)
2464       {
2465         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
2466         if (anIntStyle < 0
2467          || anIntStyle >= Aspect_HS_NB)
2468         {
2469           std::cout << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!\n";
2470           return 1;
2471         }
2472         aChangeSet->StdHatchStyle = anIntStyle;
2473       }
2474       else
2475       {
2476         aChangeSet->PathToHatchPattern = anArgHatch;
2477       }
2478     }
2479     else if (anArg == "-setshadingmodel")
2480     {
2481       if (++anArgIter >= theArgNb)
2482       {
2483         std::cout << "Error: wrong syntax at " << anArg << "\n";
2484         return 1;
2485       }
2486       aChangeSet->ToSetShadingModel = 1;
2487       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
2488       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
2489       {
2490         std::cout << "Error: wrong syntax at " << anArg << "\n";
2491         return 1;
2492       }
2493     }
2494     else if (anArg == "-unsetshadingmodel")
2495     {
2496       aChangeSet->ToSetShadingModel = -1;
2497       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
2498     }
2499     else
2500     {
2501       std::cout << "Error: wrong syntax at " << anArg << "\n";
2502       return 1;
2503     }
2504   }
2505
2506   Standard_Boolean isFirst = Standard_True;
2507   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2508        aChangesIter.More(); aChangesIter.Next())
2509   {
2510     if (!aChangesIter.Value().Validate (!isFirst))
2511     {
2512       return 1;
2513     }
2514     isFirst = Standard_False;
2515   }
2516
2517   // special case for -defaults parameter.
2518   // all changed values will be set to DefaultDrawer.
2519   if (isDefaults)
2520   {
2521     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
2522
2523     if (aChangeSet->ToSetLineWidth != 0)
2524     {
2525       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
2526       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
2527       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
2528       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
2529     }
2530     if (aChangeSet->ToSetColor != 0)
2531     {
2532       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
2533       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
2534       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
2535       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
2536       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
2537       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
2538     }
2539     if (aChangeSet->ToSetTypeOfLine != 0)
2540     {
2541       aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2542       aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2543       aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2544       aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2545       aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2546     }
2547     if (aChangeSet->ToSetTypeOfMarker != 0)
2548     {
2549       aDrawer->PointAspect()->SetTypeOfMarker (aChangeSet->TypeOfMarker);
2550       aDrawer->PointAspect()->Aspect()->SetMarkerImage (aChangeSet->MarkerImage.IsNull()
2551                                                       ? Handle(Graphic3d_MarkerImage)()
2552                                                       : new Graphic3d_MarkerImage (aChangeSet->MarkerImage));
2553     }
2554     if (aChangeSet->ToSetMarkerSize != 0)
2555     {
2556       aDrawer->PointAspect()->SetScale (aChangeSet->MarkerSize);
2557     }
2558     if (aChangeSet->ToSetTransparency != 0)
2559     {
2560       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
2561     }
2562     if (aChangeSet->ToSetAlphaMode != 0)
2563     {
2564       aDrawer->ShadingAspect()->Aspect()->SetAlphaMode (aChangeSet->AlphaMode, aChangeSet->AlphaCutoff);
2565     }
2566     if (aChangeSet->ToSetMaterial != 0)
2567     {
2568       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
2569     }
2570     if (aChangeSet->ToSetShowFreeBoundary == 1)
2571     {
2572       aDrawer->SetFreeBoundaryDraw (Standard_True);
2573     }
2574     else if (aChangeSet->ToSetShowFreeBoundary == -1)
2575     {
2576       aDrawer->SetFreeBoundaryDraw (Standard_False);
2577     }
2578     if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2579     {
2580       aDrawer->FreeBoundaryAspect()->SetWidth (aChangeSet->FreeBoundaryWidth);
2581     }
2582     if (aChangeSet->ToSetFreeBoundaryColor != 0)
2583     {
2584       aDrawer->FreeBoundaryAspect()->SetColor (aChangeSet->FreeBoundaryColor);
2585     }
2586     if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2587     {
2588       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
2589     }
2590     if (aChangeSet->ToSetMaxParamValue != 0)
2591     {
2592       aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2593     }
2594     if (aChangeSet->ToSetShadingModel == 1)
2595     {
2596       aDrawer->ShadingAspect()->Aspect()->SetShadingModel (aChangeSet->ShadingModel);
2597     }
2598
2599     // redisplay all objects in context
2600     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2601     {
2602       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
2603       if (!aPrs.IsNull())
2604       {
2605         aCtx->Redisplay (aPrs, Standard_False);
2606       }
2607     }
2608     return 0;
2609   }
2610
2611   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2612   {
2613     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
2614     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
2615     if (aPrs.IsNull())
2616     {
2617       return 1;
2618     }
2619
2620     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
2621     Handle(AIS_ColoredShape) aColoredPrs;
2622     Standard_Boolean toDisplay = Standard_False;
2623     Standard_Boolean toRedisplay = Standard_False;
2624     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
2625     {
2626       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
2627       if (aShapePrs.IsNull())
2628       {
2629         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
2630         return 1;
2631       }
2632       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
2633       if (aColoredPrs.IsNull())
2634       {
2635         aColoredPrs = new AIS_ColoredShape (aShapePrs);
2636         if (aShapePrs->HasDisplayMode())
2637         {
2638           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
2639         }
2640         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
2641         aCtx->Remove (aShapePrs, Standard_False);
2642         GetMapOfAIS().UnBind2 (aName);
2643         GetMapOfAIS().Bind (aColoredPrs, aName);
2644         toDisplay = Standard_True;
2645         aShapePrs = aColoredPrs;
2646         aPrs      = aColoredPrs;
2647       }
2648     }
2649
2650     if (!aPrs.IsNull())
2651     {
2652       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2653       aChangeSet = &aChangesIter.ChangeValue();
2654       if (aChangeSet->ToSetVisibility == 1)
2655       {
2656         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
2657         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
2658       }
2659       else if (aChangeSet->ToSetMaterial == 1)
2660       {
2661         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
2662       }
2663       else if (aChangeSet->ToSetMaterial == -1)
2664       {
2665         aCtx->UnsetMaterial (aPrs, Standard_False);
2666       }
2667       if (aChangeSet->ToSetColor == 1)
2668       {
2669         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
2670       }
2671       else if (aChangeSet->ToSetColor == -1)
2672       {
2673         aCtx->UnsetColor (aPrs, Standard_False);
2674       }
2675       if (aChangeSet->ToSetTransparency == 1)
2676       {
2677         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
2678       }
2679       else if (aChangeSet->ToSetTransparency == -1)
2680       {
2681         aCtx->UnsetTransparency (aPrs, Standard_False);
2682       }
2683       if (aChangeSet->ToSetLineWidth == 1)
2684       {
2685         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
2686       }
2687       else if (aChangeSet->ToSetLineWidth == -1)
2688       {
2689         aCtx->UnsetWidth (aPrs, Standard_False);
2690       }
2691       else if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2692       {
2693         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
2694         toRedisplay = Standard_True;
2695       }
2696       else if (aChangeSet->ToSetSensitivity != 0)
2697       {
2698         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2699       }
2700       if (!aDrawer.IsNull())
2701       {
2702         if (aChangeSet->ToSetShowFreeBoundary == 1)
2703         {
2704           aDrawer->SetFreeBoundaryDraw (Standard_True);
2705           toRedisplay = Standard_True;
2706         }
2707         else if (aChangeSet->ToSetShowFreeBoundary == -1)
2708         {
2709           aDrawer->SetFreeBoundaryDraw (Standard_False);
2710           toRedisplay = Standard_True;
2711         }
2712         if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2713         {
2714           Handle(Prs3d_LineAspect) aBoundaryAspect =
2715               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2716           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2717           aBoundaryAspect->SetWidth (aChangeSet->FreeBoundaryWidth);
2718           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2719           toRedisplay = Standard_True;
2720         }
2721         if (aChangeSet->ToSetFreeBoundaryColor != 0)
2722         {
2723           Handle(Prs3d_LineAspect) aBoundaryAspect =
2724               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2725           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2726           aBoundaryAspect->SetColor (aChangeSet->FreeBoundaryColor);
2727           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2728           toRedisplay = Standard_True;
2729         }
2730         if (aChangeSet->ToSetTypeOfLine != 0)
2731         {
2732           aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2733           aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2734           aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2735           aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2736           aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2737           toRedisplay = Standard_True;
2738         }
2739         if (aChangeSet->ToSetTypeOfMarker != 0)
2740         {
2741           Handle(Prs3d_PointAspect) aMarkerAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.0);
2742           *aMarkerAspect->Aspect() = *aDrawer->PointAspect()->Aspect();
2743           aMarkerAspect->SetTypeOfMarker (aChangeSet->TypeOfMarker);
2744           aMarkerAspect->Aspect()->SetMarkerImage (aChangeSet->MarkerImage.IsNull()
2745                                                  ? Handle(Graphic3d_MarkerImage)()
2746                                                  : new Graphic3d_MarkerImage (aChangeSet->MarkerImage));
2747           aDrawer->SetPointAspect (aMarkerAspect);
2748           toRedisplay = Standard_True;
2749         }
2750         if (aChangeSet->ToSetMarkerSize != 0)
2751         {
2752           Handle(Prs3d_PointAspect) aMarkerAspect = new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.0);
2753           *aMarkerAspect->Aspect() = *aDrawer->PointAspect()->Aspect();
2754           aMarkerAspect->SetScale (aChangeSet->MarkerSize);
2755           aDrawer->SetPointAspect (aMarkerAspect);
2756           toRedisplay = Standard_True;
2757         }
2758         if (aChangeSet->ToSetMaxParamValue != 0)
2759         {
2760           aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2761         }
2762         if (aChangeSet->ToSetHatch != 0)
2763         {
2764           if (!aDrawer->HasOwnShadingAspect())
2765           {
2766             aDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
2767             *aDrawer->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
2768           }
2769
2770           Handle(Graphic3d_AspectFillArea3d) anAsp = aDrawer->ShadingAspect()->Aspect();
2771           if (aChangeSet->ToSetHatch == -1)
2772           {
2773             anAsp->SetInteriorStyle (Aspect_IS_SOLID);
2774           }
2775           else
2776           {
2777             anAsp->SetInteriorStyle (Aspect_IS_HATCH);
2778             if (!aChangeSet->PathToHatchPattern.IsEmpty())
2779             {
2780               Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
2781               if (anImage->Load (TCollection_AsciiString (aChangeSet->PathToHatchPattern.ToCString())))
2782               {
2783                 anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
2784               }
2785               else
2786               {
2787                 std::cout << "Error: cannot load the following image: " << aChangeSet->PathToHatchPattern << std::endl;
2788                 return 1;
2789               }
2790             }
2791             else if (aChangeSet->StdHatchStyle != -1)
2792             {
2793               anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)aChangeSet->StdHatchStyle));
2794             }
2795           }
2796           toRedisplay = Standard_True;
2797         }
2798         if (aChangeSet->ToSetShadingModel != 0)
2799         {
2800           aDrawer->SetShadingModel ((aChangeSet->ToSetShadingModel == -1) ? Graphic3d_TOSM_DEFAULT : aChangeSet->ShadingModel, aChangeSet->ToSetShadingModel != -1);
2801           toRedisplay = Standard_True;
2802         }
2803         if (aChangeSet->ToSetAlphaMode != 0)
2804         {
2805           if (!aDrawer->HasOwnShadingAspect())
2806           {
2807             aDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
2808             *aDrawer->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
2809           }
2810           aDrawer->ShadingAspect()->Aspect()->SetAlphaMode (aChangeSet->AlphaMode, aChangeSet->AlphaCutoff);
2811           toRedisplay = Standard_True;
2812         }
2813       }
2814
2815       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
2816       {
2817         aChangeSet = &aChangesIter.ChangeValue();
2818         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
2819              aSubShapeIter.More(); aSubShapeIter.Next())
2820         {
2821           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
2822           if (aChangeSet->ToSetVisibility == 1)
2823           {
2824             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2825             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
2826           }
2827           if (aChangeSet->ToSetColor == 1)
2828           {
2829             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
2830           }
2831           if (aChangeSet->ToSetLineWidth == 1)
2832           {
2833             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
2834           }
2835           if (aChangeSet->ToSetColor     == -1
2836            || aChangeSet->ToSetLineWidth == -1)
2837           {
2838             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
2839           }
2840           if (aChangeSet->ToSetMaxParamValue != 0)
2841           {
2842             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2843             aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2844           }
2845           if (aChangeSet->ToSetSensitivity != 0)
2846           {
2847             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2848           }
2849           if (aChangeSet->ToSetShadingModel != 0)
2850           {
2851             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2852             aCurColDrawer->SetShadingModel ((aChangeSet->ToSetShadingModel == -1) ? Graphic3d_TOSM_DEFAULT : aChangeSet->ShadingModel, aChangeSet->ToSetShadingModel != -1);
2853           }
2854         }
2855       }
2856       if (toDisplay)
2857       {
2858         aCtx->Display (aPrs, Standard_False);
2859       }
2860       if (toRedisplay)
2861       {
2862         aCtx->Redisplay (aPrs, Standard_False);
2863       }
2864       else if (!aColoredPrs.IsNull())
2865       {
2866         aCtx->Redisplay (aColoredPrs, Standard_False);
2867       }
2868     }
2869   }
2870   return 0;
2871 }
2872
2873 //==============================================================================
2874 //function : VDonly2
2875 //author   : ege
2876 //purpose  : Display only a selected or named  object
2877 //           if there is no selected or named object s, nothing is done
2878 //==============================================================================
2879 static int VDonly2 (Draw_Interpretor& ,
2880                     Standard_Integer  theArgNb,
2881                     const char**      theArgVec)
2882 {
2883   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2884   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2885   if (aCtx.IsNull())
2886   {
2887     std::cerr << "Error: no active view!\n";
2888     return 1;
2889   }
2890
2891   Standard_Integer anArgIter = 1;
2892   for (; anArgIter < theArgNb; ++anArgIter)
2893   {
2894     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
2895     {
2896       break;
2897     }
2898   }
2899
2900   NCollection_Map<Handle(Standard_Transient)> aDispSet;
2901   if (anArgIter >= theArgNb)
2902   {
2903     // display only selected objects
2904     if (aCtx->NbSelected() < 1)
2905     {
2906       return 0;
2907     }
2908
2909     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
2910     {
2911       aDispSet.Add (aCtx->SelectedInteractive());
2912     }
2913   }
2914   else
2915   {
2916     // display only specified objects
2917     for (; anArgIter < theArgNb; ++anArgIter)
2918     {
2919       TCollection_AsciiString aName = theArgVec[anArgIter];
2920       Handle(AIS_InteractiveObject) aShape;
2921       if (GetMapOfAIS().Find2 (aName, aShape)
2922       && !aShape.IsNull())
2923       {
2924         aCtx->Display (aShape, Standard_False);
2925         aDispSet.Add (aShape);
2926       }
2927     }
2928   }
2929
2930   // weed out other objects
2931   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
2932   {
2933     if (aDispSet.Contains (anIter.Key1()))
2934     {
2935       continue;
2936     }
2937
2938     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
2939     {
2940       aCtx->Erase (aShape, Standard_False);
2941     }
2942   }
2943   return 0;
2944 }
2945
2946 //==============================================================================
2947 //function : VRemove
2948 //purpose  : Removes selected or named objects.
2949 //           If there is no selected or named objects,
2950 //           all objects in the viewer can be removed with argument -all.
2951 //           If -context is in arguments, the object is not deleted from the map of
2952 //           objects (deleted only from the current context).
2953 //==============================================================================
2954 int VRemove (Draw_Interpretor& theDI,
2955              Standard_Integer  theArgNb,
2956              const char**      theArgVec)
2957 {
2958   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2959   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2960   if (aCtx.IsNull())
2961   {
2962     std::cerr << "Error: no active view!\n";
2963     return 1;
2964   }
2965
2966   Standard_Boolean isContextOnly = Standard_False;
2967   Standard_Boolean toRemoveAll   = Standard_False;
2968   Standard_Boolean toPrintInfo   = Standard_True;
2969
2970   Standard_Integer anArgIter = 1;
2971   for (; anArgIter < theArgNb; ++anArgIter)
2972   {
2973     TCollection_AsciiString anArg = theArgVec[anArgIter];
2974     anArg.LowerCase();
2975     if (anArg == "-context")
2976     {
2977       isContextOnly = Standard_True;
2978     }
2979     else if (anArg == "-all")
2980     {
2981       toRemoveAll = Standard_True;
2982     }
2983     else if (anArg == "-noinfo")
2984     {
2985       toPrintInfo = Standard_False;
2986     }
2987     else if (anUpdateTool.parseRedrawMode (anArg))
2988     {
2989       continue;
2990     }
2991     else
2992     {
2993       break;
2994     }
2995   }
2996   if (toRemoveAll
2997    && anArgIter < theArgNb)
2998   {
2999     std::cerr << "Error: wrong syntax!\n";
3000     return 1;
3001   }
3002
3003   NCollection_List<TCollection_AsciiString> anIONameList;
3004   if (toRemoveAll)
3005   {
3006     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3007          anIter.More(); anIter.Next())
3008     {
3009       anIONameList.Append (anIter.Key2());
3010     }
3011   }
3012   else if (anArgIter < theArgNb) // removed objects names are in argument list
3013   {
3014     for (; anArgIter < theArgNb; ++anArgIter)
3015     {
3016       TCollection_AsciiString aName = theArgVec[anArgIter];
3017       Handle(AIS_InteractiveObject) anIO;
3018       if (!GetMapOfAIS().Find2 (aName, anIO))
3019       {
3020         theDI << aName << " was not bound to some object.\n";
3021         continue;
3022       }
3023
3024       if (anIO->GetContext() != aCtx)
3025       {
3026         theDI << aName << " was not displayed in current context.\n";
3027         theDI << "Please activate view with this object displayed and try again.\n";
3028         continue;
3029       }
3030
3031       anIONameList.Append (aName);
3032       continue;
3033     }
3034   }
3035   else if (aCtx->NbSelected() > 0)
3036   {
3037     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3038          anIter.More(); anIter.Next())
3039     {
3040       if (!aCtx->IsSelected (anIter.Key1()))
3041       {
3042         continue;
3043       }
3044
3045       anIONameList.Append (anIter.Key2());
3046       continue;
3047     }
3048   }
3049
3050   // Unbind all removed objects from the map of displayed IO.
3051   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
3052        anIter.More(); anIter.Next())
3053   {
3054     const Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (anIter.Value());
3055     aCtx->Remove (anIO, Standard_False);
3056     if (toPrintInfo)
3057     {
3058       theDI << anIter.Value() << " was removed\n";
3059     }
3060     if (!isContextOnly)
3061     {
3062       GetMapOfAIS().UnBind2 (anIter.Value());
3063     }
3064   }
3065   return 0;
3066 }
3067
3068 //==============================================================================
3069 //function : VErase
3070 //purpose  : Erase some selected or named objects
3071 //           if there is no selected or named objects, the whole viewer is erased
3072 //==============================================================================
3073 int VErase (Draw_Interpretor& theDI,
3074             Standard_Integer  theArgNb,
3075             const char**      theArgVec)
3076 {
3077   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
3078   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
3079   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
3080   if (aCtx.IsNull())
3081   {
3082     std::cerr << "Error: no active view!\n";
3083     return 1;
3084   }
3085
3086   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
3087
3088   Standard_Integer anArgIter = 1;
3089   Standard_Boolean toEraseInView = Standard_False;
3090   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
3091   for (; anArgIter < theArgNb; ++anArgIter)
3092   {
3093     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3094     anArgCase.LowerCase();
3095     if (anUpdateTool.parseRedrawMode (anArgCase))
3096     {
3097       continue;
3098     }
3099     else if (anArgCase == "-view"
3100           || anArgCase == "-inview")
3101     {
3102       toEraseInView = Standard_True;
3103     }
3104     else
3105     {
3106       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
3107     }
3108   }
3109
3110   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
3111   {
3112     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
3113     return 1;
3114   }
3115
3116   if (!aNamesOfEraseIO.IsEmpty())
3117   {
3118     // Erase named objects
3119     for (Standard_Integer anIter = 1; anIter <= aNamesOfEraseIO.Length(); ++anIter)
3120     {
3121       TCollection_AsciiString aName = aNamesOfEraseIO.Value (anIter);
3122       Handle(AIS_InteractiveObject) anIO;
3123       if (!GetMapOfAIS().Find2 (aName, anIO))
3124       {
3125         continue;
3126       }
3127
3128       theDI << aName << " ";
3129       if (!anIO.IsNull())
3130       {
3131         if (toEraseInView)
3132         {
3133           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3134         }
3135         else
3136         {
3137           aCtx->Erase (anIO, Standard_False);
3138         }
3139       }
3140     }
3141   }
3142   else if (!toEraseAll && aCtx->NbSelected() > 0)
3143   {
3144     // Erase selected objects
3145     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3146          anIter.More(); anIter.Next())
3147     {
3148       const Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3149       if (!anIO.IsNull()
3150        && aCtx->IsSelected (anIO))
3151       {
3152         theDI << anIter.Key2() << " ";
3153         if (toEraseInView)
3154         {
3155           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3156         }
3157       }
3158     }
3159
3160     if (!toEraseInView)
3161     {
3162       aCtx->EraseSelected (Standard_False);
3163     }
3164   }
3165   else
3166   {
3167     // Erase all objects
3168     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3169          anIter.More(); anIter.Next())
3170     {
3171       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3172       if (!anIO.IsNull())
3173       {
3174         if (toEraseInView)
3175         {
3176           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3177         }
3178         else
3179         {
3180           aCtx->Erase (anIO, Standard_False);
3181         }
3182       }
3183     }
3184   }
3185
3186   return 0;
3187 }
3188
3189 //==============================================================================
3190 //function : VDisplayAll
3191 //purpose  : Display all the objects of the Map
3192 //==============================================================================
3193 static int VDisplayAll (Draw_Interpretor& ,
3194                         Standard_Integer  theArgNb,
3195                         const char**      theArgVec)
3196
3197 {
3198   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3199   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3200   if (aCtx.IsNull())
3201   {
3202     std::cerr << "Error: no active view!\n";
3203     return 1;
3204   }
3205
3206   Standard_Integer anArgIter = 1;
3207   for (; anArgIter < theArgNb; ++anArgIter)
3208   {
3209     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3210     anArgCase.LowerCase();
3211     if (anUpdateTool.parseRedrawMode (anArgCase))
3212     {
3213       continue;
3214     }
3215     else
3216     {
3217       break;
3218     }
3219   }
3220   if (anArgIter < theArgNb)
3221   {
3222     std::cout << theArgVec[0] << "Error: wrong syntax\n";
3223     return 1;
3224   }
3225
3226   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3227        anIter.More(); anIter.Next())
3228   {
3229     aCtx->Erase (anIter.Key1(), Standard_False);
3230   }
3231
3232   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3233        anIter.More(); anIter.Next())
3234   {
3235     aCtx->Display (anIter.Key1(), Standard_False);
3236   }
3237   return 0;
3238 }
3239
3240 //! Auxiliary method to check if presentation exists
3241 inline Standard_Integer checkMode (const Handle(AIS_InteractiveContext)& theCtx,
3242                                    const Handle(AIS_InteractiveObject)&  theIO,
3243                                    const Standard_Integer                theMode)
3244 {
3245   if (theIO.IsNull() || theCtx.IsNull())
3246   {
3247     return -1;
3248   }
3249
3250   if (theMode != -1)
3251   {
3252     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
3253     {
3254       return theMode;
3255     }
3256   }
3257   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
3258   {
3259     return theIO->DisplayMode();
3260   }
3261   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
3262   {
3263     return theCtx->DisplayMode();
3264   }
3265
3266   return -1;
3267 }
3268
3269 enum ViewerTest_BndAction
3270 {
3271   BndAction_Hide,
3272   BndAction_Show,
3273   BndAction_Print
3274 };
3275
3276 //! Auxiliary method to print bounding box of presentation
3277 inline void bndPresentation (Draw_Interpretor&                         theDI,
3278                              const Handle(PrsMgr_PresentationManager)& theMgr,
3279                              const Handle(AIS_InteractiveObject)&      theObj,
3280                              const Standard_Integer                    theDispMode,
3281                              const TCollection_AsciiString&            theName,
3282                              const ViewerTest_BndAction                theAction,
3283                              const Handle(Prs3d_Drawer)&               theStyle)
3284 {
3285   switch (theAction)
3286   {
3287     case BndAction_Hide:
3288     {
3289       theMgr->Unhighlight (theObj);
3290       break;
3291     }
3292     case BndAction_Show:
3293     {
3294       theMgr->Color (theObj, theStyle, theDispMode);
3295       break;
3296     }
3297     case BndAction_Print:
3298     {
3299       Bnd_Box aBox;
3300       for (PrsMgr_Presentations::Iterator aPrsIter (theObj->Presentations()); aPrsIter.More(); aPrsIter.Next())
3301       {
3302         if (aPrsIter.Value().Mode() != theDispMode)
3303           continue;
3304
3305         aBox = aPrsIter.Value().Presentation()->Presentation()->MinMaxValues();
3306       }
3307       gp_Pnt aMin = aBox.CornerMin();
3308       gp_Pnt aMax = aBox.CornerMax();
3309       theDI << theName  << "\n"
3310             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
3311             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
3312       break;
3313     }
3314   }
3315 }
3316
3317 //==============================================================================
3318 //function : VBounding
3319 //purpose  :
3320 //==============================================================================
3321 int VBounding (Draw_Interpretor& theDI,
3322                Standard_Integer  theArgNb,
3323                const char**      theArgVec)
3324 {
3325   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3326   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3327   if (aCtx.IsNull())
3328   {
3329     std::cout << "Error: no active view!\n";
3330     return 1;
3331   }
3332
3333   ViewerTest_BndAction anAction = BndAction_Show;
3334   Standard_Integer     aMode    = -1;
3335
3336   Handle(Prs3d_Drawer) aStyle;
3337
3338   Standard_Integer anArgIter = 1;
3339   for (; anArgIter < theArgNb; ++anArgIter)
3340   {
3341     TCollection_AsciiString anArg (theArgVec[anArgIter]);
3342     anArg.LowerCase();
3343     if (anArg == "-print")
3344     {
3345       anAction = BndAction_Print;
3346     }
3347     else if (anArg == "-show")
3348     {
3349       anAction = BndAction_Show;
3350     }
3351     else if (anArg == "-hide")
3352     {
3353       anAction = BndAction_Hide;
3354     }
3355     else if (anArg == "-mode")
3356     {
3357       if (++anArgIter >= theArgNb)
3358       {
3359         std::cout << "Error: wrong syntax at " << anArg << "\n";
3360         return 1;
3361       }
3362       aMode = Draw::Atoi (theArgVec[anArgIter]);
3363     }
3364     else if (!anUpdateTool.parseRedrawMode (anArg))
3365     {
3366       break;
3367     }
3368   }
3369
3370   if (anAction == BndAction_Show)
3371   {
3372     aStyle = new Prs3d_Drawer();
3373     aStyle->SetMethod (Aspect_TOHM_BOUNDBOX);
3374     aStyle->SetColor  (Quantity_NOC_GRAY99);
3375   }
3376
3377   Standard_Integer aHighlightedMode = -1;
3378   if (anArgIter < theArgNb)
3379   {
3380     // has a list of names
3381     for (; anArgIter < theArgNb; ++anArgIter)
3382     {
3383       TCollection_AsciiString aName = theArgVec[anArgIter];
3384       Handle(AIS_InteractiveObject) anIO;
3385       if (!GetMapOfAIS().Find2 (aName, anIO))
3386       {
3387         std::cout << "Error: presentation " << aName << " does not exist\n";
3388         return 1;
3389       }
3390
3391       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3392       if (aHighlightedMode == -1)
3393       {
3394         std::cout << "Error: object " << aName << " has no presentation with mode " << aMode << std::endl;
3395         return 1;
3396       }
3397       bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, aName, anAction, aStyle);
3398     }
3399   }
3400   else if (aCtx->NbSelected() > 0)
3401   {
3402     // remove all currently selected objects
3403     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3404     {
3405       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
3406       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3407       if (aHighlightedMode != -1)
3408       {
3409         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode,
3410           GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction, aStyle);
3411       }
3412     }
3413   }
3414   else
3415   {
3416     // all objects
3417     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3418          anIter.More(); anIter.Next())
3419     {
3420       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3421       aHighlightedMode = checkMode (aCtx, anIO, aMode);
3422       if (aHighlightedMode != -1)
3423       {
3424         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, anIter.Key2(), anAction, aStyle);
3425       }
3426     }
3427   }
3428   return 0;
3429 }
3430
3431 //==============================================================================
3432 //function : VTexture
3433 //purpose  :
3434 //==============================================================================
3435 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
3436 {
3437   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3438   if (aCtx.IsNull())
3439   {
3440     std::cout << "Error: no active view!\n";
3441     return 1;
3442   }
3443
3444   int  toModulate     = -1;
3445   bool toSetFilter    = false;
3446   bool toSetAniso     = false;
3447   bool toSetTrsfAngle = false;
3448   bool toSetTrsfTrans = false;
3449   bool toSetTrsfScale = false;
3450   Standard_ShortReal aTrsfRotAngle = 0.0f;
3451   Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f);
3452   Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f);
3453   Graphic3d_TypeOfTextureFilter      aFilter       = Graphic3d_TOTF_NEAREST;
3454   Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
3455
3456   Handle(AIS_InteractiveObject) aTexturedIO;
3457   Handle(AIS_Shape) aTexturedShape;
3458   Handle(Graphic3d_TextureSet) aTextureSetOld;
3459   NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
3460   bool toSetGenRepeat = false;
3461   bool toSetGenScale  = false;
3462   bool toSetGenOrigin = false;
3463   bool toSetImage     = false;
3464   bool toComputeUV    = false;
3465
3466   const TCollection_AsciiString aCommandName (theArgVec[0]);
3467   bool toSetDefaults = aCommandName == "vtexdefault";
3468
3469   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3470   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
3471   {
3472     const TCollection_AsciiString aName     = theArgVec[anArgIter];
3473     TCollection_AsciiString       aNameCase = aName;
3474     aNameCase.LowerCase();
3475     if (anUpdateTool.parseRedrawMode (aName))
3476     {
3477       continue;
3478     }
3479     else if (aTexturedIO.IsNull())
3480     {
3481       const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
3482       if (aMapOfIO.IsBound2 (aName))
3483       {
3484         aTexturedIO = aMapOfIO.Find2 (aName);
3485         aTexturedShape = Handle(AIS_Shape)::DownCast (aTexturedIO);
3486       }
3487       if (aTexturedIO.IsNull())
3488       {
3489         std::cout << "Syntax error: shape " << aName << " does not exists in the viewer.\n";
3490         return 1;
3491       }
3492
3493       if (aTexturedIO->Attributes()->HasOwnShadingAspect())
3494       {
3495         aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
3496       }
3497     }
3498     else if (!aTexturedShape.IsNull()
3499           && (aNameCase == "-scale"
3500            || aNameCase == "-setscale"
3501            || aCommandName == "vtexscale"))
3502     {
3503       if (aCommandName != "vtexscale")
3504       {
3505         ++anArgIter;
3506       }
3507       if (anArgIter < theArgsNb)
3508       {
3509         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3510         TCollection_AsciiString aValUCase = aValU;
3511         aValUCase.LowerCase();
3512         toSetGenScale = true;
3513         if (aValUCase == "off")
3514         {
3515           aTexturedShape->SetTextureScaleUV (gp_Pnt2d (1.0, 1.0));
3516           continue;
3517         }
3518         else if (anArgIter + 1 < theArgsNb)
3519         {
3520           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3521           if (aValU.IsRealValue()
3522            && aValV.IsRealValue())
3523           {
3524             aTexturedShape->SetTextureScaleUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3525             ++anArgIter;
3526             continue;
3527           }
3528         }
3529       }
3530       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3531       return 1;
3532     }
3533     else if (!aTexturedShape.IsNull()
3534           && (aNameCase == "-origin"
3535            || aNameCase == "-setorigin"
3536            || aCommandName == "vtexorigin"))
3537     {
3538       if (aCommandName != "vtexorigin")
3539       {
3540         ++anArgIter;
3541       }
3542       if (anArgIter < theArgsNb)
3543       {
3544         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3545         TCollection_AsciiString aValUCase = aValU;
3546         aValUCase.LowerCase();
3547         toSetGenOrigin = true;
3548         if (aValUCase == "off")
3549         {
3550           aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
3551           continue;
3552         }
3553         else if (anArgIter + 1 < theArgsNb)
3554         {
3555           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3556           if (aValU.IsRealValue()
3557            && aValV.IsRealValue())
3558           {
3559             aTexturedShape->SetTextureOriginUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3560             ++anArgIter;
3561             continue;
3562           }
3563         }
3564       }
3565       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3566       return 1;
3567     }
3568     else if (!aTexturedShape.IsNull()
3569           && (aNameCase == "-repeat"
3570            || aNameCase == "-setrepeat"
3571            || aCommandName == "vtexrepeat"))
3572     {
3573       if (aCommandName != "vtexrepeat")
3574       {
3575         ++anArgIter;
3576       }
3577       if (anArgIter < theArgsNb)
3578       {
3579         TCollection_AsciiString aValU (theArgVec[anArgIter]);
3580         TCollection_AsciiString aValUCase = aValU;
3581         aValUCase.LowerCase();
3582         toSetGenRepeat = true;
3583         if (aValUCase == "off")
3584         {
3585           aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
3586           continue;
3587         }
3588         else if (anArgIter + 1 < theArgsNb)
3589         {
3590           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
3591           if (aValU.IsRealValue()
3592            && aValV.IsRealValue())
3593           {
3594             aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
3595             ++anArgIter;
3596             continue;
3597           }
3598         }
3599       }
3600       std::cout << "Syntax error: unexpected argument '" << aName << "'\n";
3601       return 1;
3602     }
3603     else if (aNameCase == "-modulate")
3604     {
3605       bool toModulateBool = true;
3606       if (anArgIter + 1 < theArgsNb
3607        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toModulateBool))
3608       {
3609         ++anArgIter;
3610       }
3611       toModulate = toModulateBool ? 1 : 0;
3612     }
3613     else if ((aNameCase == "-setfilter"
3614            || aNameCase == "-filter")
3615            && anArgIter + 1 < theArgsNb)
3616     {
3617       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
3618       aValue.LowerCase();
3619       ++anArgIter;
3620       toSetFilter = true;
3621       if (aValue == "nearest")
3622       {
3623         aFilter = Graphic3d_TOTF_NEAREST;
3624       }
3625       else if (aValue == "bilinear")
3626       {
3627         aFilter = Graphic3d_TOTF_BILINEAR;
3628       }
3629       else if (aValue == "trilinear")
3630       {
3631         aFilter = Graphic3d_TOTF_TRILINEAR;
3632       }
3633       else
3634       {
3635         std::cout << "Syntax error: unexpected argument '" << aValue << "'\n";
3636         return 1;
3637       }
3638     }
3639     else if ((aNameCase == "-setaniso"