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