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