7698ebd1ffaf81cc28896e4c10fa526ac0e023f5
[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   Standard_Boolean      toPrintInfo   = Standard_True;
2032
2033   Standard_Integer anArgIter = 1;
2034   for (; anArgIter < theArgNb; ++anArgIter)
2035   {
2036     TCollection_AsciiString anArg = theArgVec[anArgIter];
2037     anArg.LowerCase();
2038     if (anArg == "-context")
2039     {
2040       isContextOnly = Standard_True;
2041     }
2042     else if (anArg == "-all")
2043     {
2044       toRemoveAll = Standard_True;
2045     }
2046     else if (anArg == "-noinfo")
2047     {
2048       toPrintInfo = Standard_False;
2049     }
2050     else if (!parseRedrawMode (anArg, aToUpdate))
2051     {
2052       break;
2053     }
2054   }
2055   if (toRemoveAll
2056    && anArgIter < theArgNb)
2057   {
2058     std::cout << "Error: wrong syntax!\n";
2059     return 1;
2060   }
2061
2062   NCollection_List<TCollection_AsciiString> anIONameList;
2063   if (toRemoveAll)
2064   {
2065     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2066          anIter.More(); anIter.Next())
2067     {
2068       anIONameList.Append (anIter.Key2());
2069     }
2070   }
2071   else if (anArgIter < theArgNb) // removed objects names are in argument list
2072   {
2073     for (; anArgIter < theArgNb; ++anArgIter)
2074     {
2075       TCollection_AsciiString aName = theArgVec[anArgIter];
2076       if (!GetMapOfAIS().IsBound2 (aName))
2077       {
2078         theDI << aName.ToCString() << " was not bound to some object.\n";
2079         continue;
2080       }
2081
2082       const Handle(Standard_Transient)& aTransientObj = GetMapOfAIS().Find2 (aName);
2083
2084       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aTransientObj);
2085       if (!anIO.IsNull())
2086       {
2087         if (anIO->GetContext() != TheAISContext())
2088         {
2089           theDI << aName.ToCString() << " was not displayed in current context.\n";
2090           theDI << "Please activate view with this object displayed and try again.\n";
2091           continue;
2092         }
2093
2094         anIONameList.Append (aName);
2095         continue;
2096       }
2097
2098       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (aTransientObj);
2099       if (!aNisIO.IsNull())
2100       {
2101         anIONameList.Append (aName);
2102       }
2103     }
2104   }
2105   else if (TheAISContext()->NbCurrents() > 0
2106         || TheNISContext()->GetSelected().Extent() > 0)
2107   {
2108     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2109          anIter.More(); anIter.Next())
2110     {
2111       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2112       if (!anIO.IsNull())
2113       {
2114         if (!TheAISContext()->IsCurrent (anIO))
2115         {
2116           continue;
2117         }
2118
2119         anIONameList.Append (anIter.Key2());
2120         continue;
2121       }
2122
2123       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2124       if (!aNisIO.IsNull())
2125       {
2126         if (!TheNISContext()->IsSelected (aNisIO))
2127         {
2128           continue;
2129         }
2130
2131         anIONameList.Append (anIter.Key2());
2132       }
2133     }
2134   }
2135
2136   // Unbind all removed objects from the map of displayed IO.
2137   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
2138        anIter.More(); anIter.Next())
2139   {
2140     const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2141     if (!anIO.IsNull())
2142     {
2143       TheAISContext()->Remove (anIO, Standard_False);
2144       if (toPrintInfo)
2145       {
2146         theDI << anIter.Value().ToCString() << " was removed\n";
2147       }
2148     }
2149     else
2150     {
2151       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2152       if (!aNisIO.IsNull())
2153       {
2154         TheNISContext()->Remove (aNisIO);
2155         if (toPrintInfo)
2156         {
2157           theDI << anIter.Value().ToCString() << " was removed\n";
2158         }
2159       }
2160     }
2161     if (!isContextOnly)
2162     {
2163       GetMapOfAIS().UnBind2 (anIter.Value());
2164     }
2165   }
2166
2167   // update the screen and redraw the view
2168   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2169   a3DView()->SetImmediateUpdate (isAutoUpdate);
2170   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2171    || aToUpdate == ViewerTest_RM_RedrawForce)
2172   {
2173     TheAISContext()->UpdateCurrentViewer();
2174   }
2175
2176   return 0;
2177 }
2178
2179 //==============================================================================
2180 //function : VErase
2181 //purpose  : Erase some selected or named objects
2182 //           if there is no selected or named objects, the whole viewer is erased
2183 //==============================================================================
2184 int VErase (Draw_Interpretor& theDI,
2185             Standard_Integer  theArgNb,
2186             const char**      theArgVec)
2187 {
2188   if (a3DView().IsNull())
2189   {
2190     std::cout << "Error: no active view!\n";
2191     return 1;
2192   }
2193   TheAISContext()->CloseAllContexts (Standard_False);
2194
2195   ViewerTest_RedrawMode  aToUpdate  = ViewerTest_RM_Auto;
2196   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
2197
2198   Standard_Integer anArgIter = 1;
2199   for (; anArgIter < theArgNb; ++anArgIter)
2200   {
2201     if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate))
2202     {
2203       break;
2204     }
2205   }
2206
2207   if (anArgIter < theArgNb)
2208   {
2209     if (toEraseAll)
2210     {
2211       std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
2212       return 1;
2213     }
2214
2215     // has a list of names
2216     for (; anArgIter < theArgNb; ++anArgIter)
2217     {
2218       TCollection_AsciiString aName = theArgVec[anArgIter];
2219       if (!GetMapOfAIS().IsBound2 (aName))
2220       {
2221         continue;
2222       }
2223
2224       const Handle(Standard_Transient)    anObj = GetMapOfAIS().Find2 (aName);
2225       const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (anObj);
2226       theDI << aName.ToCString() << " ";
2227       if (!anIO.IsNull())
2228       {
2229         TheAISContext()->Erase (anIO, Standard_False);
2230       }
2231       else
2232       {
2233         const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anObj);
2234         if (!aNisIO.IsNull())
2235         {
2236           TheNISContext()->Erase (aNisIO);
2237         }
2238       }
2239     }
2240   }
2241   else if (!toEraseAll
2242         && TheAISContext()->NbCurrents() > 0)
2243   {
2244     // remove all currently selected objects
2245     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2246          anIter.More(); anIter.Next())
2247     {
2248       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2249       if (!anIO.IsNull()
2250        && TheAISContext()->IsCurrent (anIO))
2251       {
2252         theDI << anIter.Key2().ToCString() << " ";
2253         TheAISContext()->Erase (anIO, Standard_False);
2254       }
2255     }
2256   }
2257   else
2258   {
2259     // erase entire viewer
2260     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2261          anIter.More(); anIter.Next())
2262     {
2263       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2264       if (!anIO.IsNull())
2265       {
2266         TheAISContext()->Erase (anIO, Standard_False);
2267       }
2268       else
2269       {
2270         const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2271         if (!aNisIO.IsNull())
2272         {
2273           TheNISContext()->Erase (aNisIO);
2274         }
2275       }
2276     }
2277   }
2278
2279   // update the screen and redraw the view
2280   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2281   a3DView()->SetImmediateUpdate (isAutoUpdate);
2282   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2283    || aToUpdate == ViewerTest_RM_RedrawForce)
2284   {
2285     TheAISContext()->UpdateCurrentViewer();
2286   }
2287
2288   return 0;
2289 }
2290
2291 //==============================================================================
2292 //function : VDisplayAll
2293 //author   : ege
2294 //purpose  : Display all the objects of the Map
2295 //==============================================================================
2296 static int VDisplayAll (Draw_Interpretor& ,
2297                         Standard_Integer  theArgNb,
2298                         const char**      theArgVec)
2299
2300 {
2301   if (a3DView().IsNull())
2302   {
2303     std::cout << "Error: no active view!\n";
2304     return 1;
2305   }
2306
2307   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
2308
2309   Standard_Integer anArgIter = 1;
2310   for (; anArgIter < theArgNb; ++anArgIter)
2311   {
2312     if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate))
2313     {
2314       break;
2315     }
2316   }
2317   if (anArgIter < theArgNb)
2318   {
2319     std::cout << theArgVec[0] << "Error: wrong syntax\n";
2320     return 1;
2321   }
2322
2323   if (TheAISContext()->HasOpenedContext())
2324   {
2325     TheAISContext()->CloseLocalContext();
2326   }
2327
2328   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2329        anIter.More(); anIter.Next())
2330   {
2331     if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
2332     {
2333       const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2334       TheAISContext()->Erase (aShape, Standard_False);
2335     }
2336     else if (anIter.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject)))
2337     {
2338       const Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2339       TheNISContext()->Erase (aShape);
2340     }
2341   }
2342
2343   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2344        anIter.More(); anIter.Next())
2345   {
2346     if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
2347     {
2348       const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2349       TheAISContext()->Display (aShape, Standard_False);
2350     }
2351     else if (anIter.Key1()->IsKind (STANDARD_TYPE(NIS_InteractiveObject)))
2352     {
2353       Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2354       TheNISContext()->Display (aShape);
2355     }
2356   }
2357
2358   // update the screen and redraw the view
2359   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2360   a3DView()->SetImmediateUpdate (isAutoUpdate);
2361   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2362    || aToUpdate == ViewerTest_RM_RedrawForce)
2363   {
2364     TheAISContext()->UpdateCurrentViewer();
2365   }
2366
2367   return 0;
2368 }
2369
2370 //! Auxiliary method to find presentation
2371 inline Handle(PrsMgr_Presentation) findPresentation (const Handle(AIS_InteractiveContext)& theCtx,
2372                                                      const Handle(AIS_InteractiveObject)&  theIO,
2373                                                      const Standard_Integer                theMode)
2374 {
2375   if (theIO.IsNull())
2376   {
2377     return Handle(PrsMgr_Presentation)();
2378   }
2379
2380   if (theMode != -1)
2381   {
2382     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
2383     {
2384       return theCtx->MainPrsMgr()->Presentation (theIO, theMode);
2385     }
2386   }
2387   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
2388   {
2389     return theCtx->MainPrsMgr()->Presentation (theIO, theIO->DisplayMode());
2390   }
2391   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
2392   {
2393     return theCtx->MainPrsMgr()->Presentation (theIO, theCtx->DisplayMode());
2394   }
2395   return Handle(PrsMgr_Presentation)();
2396 }
2397
2398 enum ViewerTest_BndAction
2399 {
2400   BndAction_Hide,
2401   BndAction_Show,
2402   BndAction_Print
2403 };
2404
2405 //! Auxiliary method to print bounding box of presentation
2406 inline void bndPresentation (Draw_Interpretor&                  theDI,
2407                              const Handle(PrsMgr_Presentation)& thePrs,
2408                              const TCollection_AsciiString&     theName,
2409                              const ViewerTest_BndAction         theAction)
2410 {
2411   switch (theAction)
2412   {
2413     case BndAction_Hide:
2414     {
2415       thePrs->Presentation()->GraphicUnHighlight();
2416       break;
2417     }
2418     case BndAction_Show:
2419     {
2420       thePrs->Presentation()->BoundBox();
2421       break;
2422     }
2423     case BndAction_Print:
2424     {
2425       Graphic3d_Vec3d aMin, aMax;
2426       thePrs->Presentation()->MinMaxValues (aMin.x(), aMin.y(), aMin.z(),
2427                                             aMax.x(), aMax.y(), aMax.z());
2428       theDI << theName  << "\n"
2429             << aMin.x() << " " << aMin.y() << " " << aMin.z() << " "
2430             << aMax.x() << " " << aMax.y() << " " << aMax.z() << "\n";
2431       break;
2432     }
2433   }
2434 }
2435
2436 //==============================================================================
2437 //function : VBounding
2438 //purpose  :
2439 //==============================================================================
2440 int VBounding (Draw_Interpretor& theDI,
2441                Standard_Integer  theArgNb,
2442                const char**      theArgVec)
2443 {
2444   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2445   if (aCtx.IsNull())
2446   {
2447     std::cout << "Error: no active view!\n";
2448     return 1;
2449   }
2450
2451   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
2452   ViewerTest_BndAction  anAction  = BndAction_Show;
2453   Standard_Integer      aMode     = -1;
2454
2455   Standard_Integer anArgIter = 1;
2456   for (; anArgIter < theArgNb; ++anArgIter)
2457   {
2458     TCollection_AsciiString anArg (theArgVec[anArgIter]);
2459     anArg.LowerCase();
2460     if (anArg == "-print")
2461     {
2462       anAction = BndAction_Print;
2463     }
2464     else if (anArg == "-show")
2465     {
2466       anAction = BndAction_Show;
2467     }
2468     else if (anArg == "-hide")
2469     {
2470       anAction = BndAction_Hide;
2471     }
2472     else if (anArg == "-mode")
2473     {
2474       if (++anArgIter >= theArgNb)
2475       {
2476         std::cout << "Error: wrong syntax at " << anArg << "\n";
2477         return 1;
2478       }
2479       aMode = Draw::Atoi (theArgVec[anArgIter]);
2480     }
2481     else if (!parseRedrawMode (anArg, aToUpdate))
2482     {
2483       break;
2484     }
2485   }
2486
2487   if (anArgIter < theArgNb)
2488   {
2489     // has a list of names
2490     for (; anArgIter < theArgNb; ++anArgIter)
2491     {
2492       TCollection_AsciiString aName = theArgVec[anArgIter];
2493       if (!GetMapOfAIS().IsBound2 (aName))
2494       {
2495         std::cout << "Error: presentation " << aName << " does not exist\n";
2496         return 1;
2497       }
2498
2499       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2500       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
2501       if (aPrs.IsNull())
2502       {
2503         std::cout << "Error: presentation " << aName << " does not exist\n";
2504         return 1;
2505       }
2506       bndPresentation (theDI, aPrs, aName, anAction);
2507     }
2508   }
2509   else if (TheAISContext()->NbCurrents() > 0)
2510   {
2511     // remove all currently selected objects
2512     for (aCtx->InitCurrent(); aCtx->MoreCurrent(); aCtx->NextCurrent())
2513     {
2514       Handle(AIS_InteractiveObject) anIO = aCtx->Current();
2515       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
2516       if (!aPrs.IsNull())
2517       {
2518         bndPresentation (theDI, aPrs, GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction);
2519       }
2520     }
2521   }
2522   else
2523   {
2524     // all objects
2525     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2526          anIter.More(); anIter.Next())
2527     {
2528       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2529       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
2530       if (!aPrs.IsNull())
2531       {
2532         bndPresentation (theDI, aPrs, anIter.Key2(), anAction);
2533       }
2534     }
2535   }
2536
2537   // update the screen and redraw the view
2538   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2539   a3DView()->SetImmediateUpdate (isAutoUpdate);
2540   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2541    || aToUpdate == ViewerTest_RM_RedrawForce)
2542   {
2543     TheAISContext()->UpdateCurrentViewer();
2544   }
2545
2546   return 0;
2547 }
2548
2549 //==============================================================================
2550 //function : VTexture
2551 //purpose  :
2552 //==============================================================================
2553 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgv)
2554 {
2555   TCollection_AsciiString aCommandName (theArgv[0]);
2556
2557   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
2558   if (aCommandName == "vtexture")
2559   {
2560     if (theArgsNb < 2)
2561     {
2562       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
2563       std::cout << "Type help for more information.\n";
2564       return 1;
2565     }
2566
2567     // look for options of vtexture command
2568     TCollection_AsciiString aParseKey;
2569     for (Standard_Integer anArgIt = 2; anArgIt < theArgsNb; ++anArgIt)
2570     {
2571       TCollection_AsciiString anArg (theArgv [anArgIt]);
2572
2573       anArg.UpperCase();
2574       if (anArg.Value (1) == '-' && !anArg.IsRealValue())
2575       {
2576         aParseKey = anArg;
2577         aParseKey.Remove (1);
2578         aParseKey.UpperCase();
2579         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
2580         continue;
2581       }
2582
2583       if (aParseKey.IsEmpty())
2584       {
2585         continue;
2586       }
2587
2588       aMapOfArgs(aParseKey)->Append (anArg);
2589     }
2590   }
2591   else if (aCommandName == "vtexscale"
2592         || aCommandName == "vtexorigin"
2593         || aCommandName == "vtexrepeat")
2594   {
2595     // scan for parameters of vtexscale, vtexorigin, vtexrepeat commands
2596     // equal to -scale, -origin, -repeat options of vtexture command
2597     if (theArgsNb < 2 || theArgsNb > 4)
2598     {
2599       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
2600       std::cout << "Type help for more information.\n";
2601       return 1;
2602     }
2603
2604     Handle(TColStd_HSequenceOfAsciiString) anArgs = new TColStd_HSequenceOfAsciiString;
2605     if (theArgsNb == 2)
2606     {
2607       anArgs->Append ("OFF");
2608     }
2609     else if (theArgsNb == 4)
2610     {
2611       anArgs->Append (TCollection_AsciiString (theArgv[2]));
2612       anArgs->Append (TCollection_AsciiString (theArgv[3]));
2613     }
2614
2615     TCollection_AsciiString anArgKey;
2616     if (aCommandName == "vtexscale")
2617     {
2618       anArgKey = "SCALE";
2619     }
2620     else if (aCommandName == "vtexorigin")
2621     {
2622       anArgKey = "ORIGIN";
2623     }
2624     else
2625     {
2626       anArgKey = "REPEAT";
2627     }
2628
2629     aMapOfArgs.Bind (anArgKey, anArgs);
2630   }
2631   else if (aCommandName == "vtexdefault")
2632   {
2633     // scan for parameters of vtexdefault command
2634     // equal to -default option of vtexture command
2635     aMapOfArgs.Bind ("DEFAULT", new TColStd_HSequenceOfAsciiString);
2636   }
2637
2638   // Check arguments for validity
2639   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
2640   for (; aMapIt.More(); aMapIt.Next())
2641   {
2642     const TCollection_AsciiString& aKey = aMapIt.Key();
2643     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
2644
2645     // -scale, -origin, -repeat: one argument "off", or two real values
2646     if ((aKey.IsEqual ("SCALE") || aKey.IsEqual ("ORIGIN") || aKey.IsEqual ("REPEAT"))
2647       && ((anArgs->Length() == 1 && anArgs->Value(1) == "OFF")
2648        || (anArgs->Length() == 2 && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue())))
2649     {
2650       continue;
2651     }
2652
2653     // -modulate: single argument "on" / "off"
2654     if (aKey.IsEqual ("MODULATE") && anArgs->Length() == 1 && (anArgs->Value(1) == "OFF" || anArgs->Value(1) == "ON"))
2655     {
2656       continue;
2657     }
2658
2659     // -default: no arguments
2660     if (aKey.IsEqual ("DEFAULT") && anArgs->IsEmpty())
2661     {
2662       continue;
2663     }
2664
2665     TCollection_AsciiString aLowerKey;
2666     aLowerKey  = "-";
2667     aLowerKey += aKey;
2668     aLowerKey.LowerCase();
2669     std::cout << theArgv[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
2670     std::cout << "Type help for more information.\n";
2671     return 1;
2672   }
2673
2674   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
2675   if (anAISContext.IsNull())
2676   {
2677     std::cout << aCommandName << ": " << " please use 'vinit' command to initialize view.\n";
2678     return 1;
2679   }
2680
2681   Standard_Integer aPreviousMode = 0;
2682
2683   ViewerTest::CurrentView()->SetSurfaceDetail (V3d_TEX_ALL);
2684
2685   TCollection_AsciiString aShapeName (theArgv[1]);
2686   Handle(AIS_InteractiveObject) anIO;
2687
2688   const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
2689   if (aMapOfIO.IsBound2 (aShapeName))
2690   {
2691     anIO = Handle(AIS_InteractiveObject)::DownCast (aMapOfIO.Find2 (aShapeName));
2692   }
2693
2694   if (anIO.IsNull())
2695   {
2696     std::cout << aCommandName << ": shape " << aShapeName << " does not exists.\n";
2697     return 1;
2698   }
2699
2700   Handle(AIS_TexturedShape) aTexturedIO;
2701   if (anIO->IsKind (STANDARD_TYPE (AIS_TexturedShape)))
2702   {
2703     aTexturedIO = Handle(AIS_TexturedShape)::DownCast (anIO);
2704     aPreviousMode = aTexturedIO->DisplayMode();
2705   }
2706   else
2707   {
2708     anAISContext->Clear (anIO, Standard_False);
2709     aTexturedIO = new AIS_TexturedShape (DBRep::Get (theArgv[1]));
2710     GetMapOfAIS().UnBind1 (anIO);
2711     GetMapOfAIS().UnBind2 (aShapeName);
2712     GetMapOfAIS().Bind (aTexturedIO, aShapeName);
2713   }
2714
2715   // -------------------------------------------
2716   //  Turn texturing on/off - only for vtexture
2717   // -------------------------------------------
2718
2719   if (aCommandName == "vtexture")
2720   {
2721     TCollection_AsciiString aTextureArg (theArgsNb > 2 ? theArgv[2] : "");
2722
2723     if (aTextureArg.IsEmpty())
2724     {
2725       std::cout << aCommandName << ": " << " Texture mapping disabled.\n";
2726       std::cout << "To enable it, use 'vtexture NameOfShape NameOfTexture'\n" << "\n";
2727
2728       anAISContext->SetDisplayMode (aTexturedIO, AIS_Shaded, Standard_False);
2729       if (aPreviousMode == 3)
2730       {
2731         anAISContext->RecomputePrsOnly (aTexturedIO);
2732       }
2733
2734       anAISContext->Display (aTexturedIO, Standard_True);
2735       return 0;
2736     }
2737     else if (aTextureArg.Value(1) != '-') // "-option" on place of texture argument
2738     {
2739       if (aTextureArg == "?")
2740       {
2741         TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
2742
2743         theDi << "\n Files in current directory : \n" << "\n";
2744         theDi.Eval ("glob -nocomplain *");
2745
2746         TCollection_AsciiString aCmnd ("glob -nocomplain ");
2747         aCmnd += aTextureFolder;
2748         aCmnd += "/* ";
2749
2750         theDi << "Files in " << aTextureFolder.ToCString() << " : \n" << "\n";
2751         theDi.Eval (aCmnd.ToCString());
2752         return 0;
2753       }
2754       else
2755       {
2756         aTexturedIO->SetTextureFileName (aTextureArg);
2757       }
2758     }
2759   }
2760
2761   // ------------------------------------
2762   //  Process other options and commands
2763   // ------------------------------------
2764
2765   Handle(TColStd_HSequenceOfAsciiString) aValues;
2766   if (aMapOfArgs.Find ("DEFAULT", aValues))
2767   {
2768     aTexturedIO->SetTextureRepeat (Standard_False);
2769     aTexturedIO->SetTextureOrigin (Standard_False);
2770     aTexturedIO->SetTextureScale  (Standard_False);
2771     aTexturedIO->EnableTextureModulate();
2772   }
2773   else
2774   {
2775     if (aMapOfArgs.Find ("SCALE", aValues))
2776     {
2777       if (aValues->Value(1) != "OFF")
2778       {
2779         aTexturedIO->SetTextureScale (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2780       }
2781       else
2782       {
2783         aTexturedIO->SetTextureScale (Standard_False);
2784       }
2785     }
2786
2787     if (aMapOfArgs.Find ("ORIGIN", aValues))
2788     {
2789       if (aValues->Value(1) != "OFF")
2790       {
2791         aTexturedIO->SetTextureOrigin (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2792       }
2793       else
2794       {
2795         aTexturedIO->SetTextureOrigin (Standard_False);
2796       }
2797     }
2798
2799     if (aMapOfArgs.Find ("REPEAT", aValues))
2800     {
2801       if (aValues->Value(1) != "OFF")
2802       {
2803         aTexturedIO->SetTextureRepeat (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2804       }
2805       else
2806       {
2807         aTexturedIO->SetTextureRepeat (Standard_False);
2808       }
2809     }
2810
2811     if (aMapOfArgs.Find ("MODULATE", aValues))
2812     {
2813       if (aValues->Value(1) == "ON")
2814       {
2815         aTexturedIO->EnableTextureModulate();
2816       }
2817       else
2818       {
2819         aTexturedIO->DisableTextureModulate();
2820       }
2821     }
2822   }
2823
2824   if (aTexturedIO->DisplayMode() == 3 || aPreviousMode == 3)
2825   {
2826     anAISContext->RecomputePrsOnly (aTexturedIO);
2827   }
2828   else
2829   {
2830     anAISContext->SetDisplayMode (aTexturedIO, 3, Standard_False);
2831     anAISContext->Display (aTexturedIO, Standard_True);
2832     anAISContext->Update (aTexturedIO,Standard_True);
2833   }
2834
2835   return 0;
2836 }
2837
2838 //==============================================================================
2839 //function : VDisplay2
2840 //author   : ege
2841 //purpose  : Display an object from its name
2842 //==============================================================================
2843 static int VDisplay2 (Draw_Interpretor& theDI,
2844                       Standard_Integer  theArgNb,
2845                       const char**      theArgVec)
2846 {
2847   if (theArgNb < 2)
2848   {
2849     std::cout << theArgVec[0] << "Error: wrong syntax!\n";
2850     return 1;
2851   }
2852   else if (a3DView().IsNull())
2853   {
2854     ViewerTest::ViewerInit();
2855     std::cout << "Command vinit should be called before!\n";
2856     // return 1;
2857   }
2858
2859   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2860   if (aCtx->HasOpenedContext())
2861   {
2862     aCtx->CloseLocalContext();
2863   }
2864
2865   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
2866   Standard_Integer      isMutable = -1;
2867   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2868   {
2869     const TCollection_AsciiString aName     = theArgVec[anArgIter];
2870     TCollection_AsciiString       aNameCase = aName;
2871     aNameCase.LowerCase();
2872     if (parseRedrawMode (aName, aToUpdate))
2873     {
2874       continue;
2875     }
2876     else if (aNameCase == "-mutable")
2877     {
2878       isMutable = 1;
2879       continue;
2880     }
2881     else if (!GetMapOfAIS().IsBound2 (aName))
2882     {
2883       // create the AIS_Shape from a name
2884       const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
2885       if (!aShape.IsNull())
2886       {
2887         if (isMutable != -1)
2888         {
2889           aShape->SetMutable (isMutable == 1);
2890         }
2891         GetMapOfAIS().Bind (aShape, aName);
2892         aCtx->Display (aShape, Standard_False);
2893       }
2894       continue;
2895     }
2896
2897     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
2898     if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject)))
2899     {
2900       Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
2901       if (isMutable != -1)
2902       {
2903         aShape->SetMutable (isMutable == 1);
2904       }
2905
2906       if (aShape->Type() == AIS_KOI_Datum)
2907       {
2908         aCtx->Display (aShape, Standard_False);
2909       }
2910       else
2911       {
2912         theDI << "Display " << aName.ToCString() << "\n";
2913         // get the Shape from a name
2914         TopoDS_Shape aNewShape = GetShapeFromName (aName.ToCString());
2915
2916         // update the Shape in the AIS_Shape
2917         Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
2918         if (!aShapePrs.IsNull())
2919         {
2920           aShapePrs->Set (aNewShape);
2921         }
2922         aCtx->Redisplay (aShape, Standard_False);
2923         aCtx->Display   (aShape, Standard_False);
2924       }
2925     }
2926     else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject)))
2927     {
2928       Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anObj);
2929       TheNISContext()->Display (aShape);
2930     }
2931   }
2932
2933   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2934   a3DView()->SetImmediateUpdate (isAutoUpdate);
2935   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2936    || aToUpdate == ViewerTest_RM_RedrawForce)
2937   {
2938     // update the screen and redraw the view
2939     aCtx->UpdateCurrentViewer();
2940   }
2941   return 0;
2942 }
2943
2944 //===============================================================================================
2945 //function : VUpdate
2946 //purpose  :
2947 //===============================================================================================
2948 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2949 {
2950   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2951   if (aContextAIS.IsNull())
2952   {
2953     std::cout << theArgVec[0] << "AIS context is not available.\n";
2954     return 1;
2955   }
2956
2957   if (theArgsNb < 2)
2958   {
2959     std::cout << theArgVec[0] << ": insufficient arguments. Type help for more information.\n";
2960     return 1;
2961   }
2962
2963   const ViewerTest_DoubleMapOfInteractiveAndName& anAISMap = GetMapOfAIS();
2964
2965   AIS_ListOfInteractive aListOfIO;
2966
2967   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
2968   {
2969     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
2970
2971     Handle(AIS_InteractiveObject) anAISObj;
2972     if (anAISMap.IsBound2 (aName))
2973     {
2974       anAISObj = Handle(AIS_InteractiveObject)::DownCast (anAISMap.Find2 (aName));
2975     }
2976
2977     if (anAISObj.IsNull())
2978     {
2979       std::cout << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".\n";
2980       return 1;
2981     }
2982
2983     aListOfIO.Append (anAISObj);
2984   }
2985
2986   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
2987   for (; anIOIt.More(); anIOIt.Next())
2988   {
2989     aContextAIS->Update (anIOIt.Value(), Standard_False);
2990   }
2991
2992   aContextAIS->UpdateCurrentViewer();
2993
2994   return 0;
2995 }
2996
2997 //==============================================================================
2998 //function : VPerf
2999 //purpose  : Test the annimation of an object along a
3000 //           predifined trajectory
3001 //Draw arg : vperf ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)
3002 //==============================================================================
3003
3004 static int VPerf(Draw_Interpretor& di, Standard_Integer , const char** argv) {
3005
3006   OSD_Timer myTimer;
3007   if (TheAISContext()->HasOpenedContext())
3008     TheAISContext()->CloseLocalContext();
3009
3010   Standard_Real Step=4*M_PI/180;
3011   Standard_Real Angle=0;
3012
3013   Handle(AIS_InteractiveObject) aIO;
3014   if (GetMapOfAIS().IsBound2(argv[1]))
3015     aIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
3016   if (aIO.IsNull())
3017     return 1;
3018
3019   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aIO);
3020
3021   myTimer.Start();
3022
3023   if (Draw::Atoi(argv[3])==1 ) {
3024     di<<" Primitives sensibles OFF"<<"\n";
3025     TheAISContext()->Deactivate(aIO);
3026   }
3027   else {
3028     di<<" Primitives sensibles ON"<<"\n";
3029   }
3030   // Movement par transformation
3031   if(Draw::Atoi(argv[2]) ==1) {
3032     di<<" Calcul par Transformation"<<"\n";
3033     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3034
3035       Angle=Step*myAngle;
3036       gp_Trsf myTransfo;
3037       myTransfo.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ) ,Angle );
3038       TheAISContext()->SetLocation(aShape,myTransfo);
3039       TheAISContext() ->UpdateCurrentViewer();
3040
3041     }
3042   }
3043   else {
3044     di<<" Calcul par Locations"<<"\n";
3045     gp_Trsf myAngleTrsf;
3046     myAngleTrsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ), Step  );
3047     TopLoc_Location myDeltaAngle (myAngleTrsf);
3048     TopLoc_Location myTrueLoc;
3049
3050     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3051
3052       Angle=Step*myAngle;
3053       myTrueLoc=myTrueLoc*myDeltaAngle;
3054       TheAISContext()->SetLocation(aShape,myTrueLoc );
3055       TheAISContext() ->UpdateCurrentViewer();
3056     }
3057   }
3058   if (Draw::Atoi(argv[3])==1 ){
3059     // On reactive la selection des primitives sensibles
3060     TheAISContext()->Activate(aIO,0);
3061   }
3062   a3DView() -> Redraw();
3063   myTimer.Stop();
3064   di<<" Temps ecoule "<<"\n";
3065   myTimer.Show();
3066   return 0;
3067 }
3068
3069
3070 //==================================================================================
3071 // Function : VAnimation
3072 //==================================================================================
3073 static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
3074   if (argc != 5) {
3075     di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile"<<"\n";
3076     return 1;
3077   }
3078
3079   Standard_Real thread = 4;
3080   Standard_Real angleA=0;
3081   Standard_Real angleB;
3082   Standard_Real X;
3083   gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
3084
3085   BRep_Builder B;
3086   TopoDS_Shape CrankArm;
3087   TopoDS_Shape CylinderHead;
3088   TopoDS_Shape Propeller;
3089   TopoDS_Shape EngineBlock;
3090
3091   //BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
3092   //BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
3093   //BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
3094   //BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
3095   BRepTools::Read(CrankArm,argv[1],B);
3096   BRepTools::Read(CylinderHead,argv[2],B);
3097   BRepTools::Read(Propeller,argv[3],B);
3098   BRepTools::Read(EngineBlock,argv[4],B);
3099
3100   if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure."<<"\n";}
3101
3102
3103   OSD_Timer myTimer;
3104   myTimer.Start();
3105
3106   Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
3107   Handle(AIS_Shape) myAisEngineBlock  = new AIS_Shape (EngineBlock);
3108   Handle(AIS_Shape) myAisCrankArm     = new AIS_Shape (CrankArm);
3109   Handle(AIS_Shape) myAisPropeller    = new AIS_Shape (Propeller);
3110
3111   GetMapOfAIS().Bind(myAisCylinderHead,"a");
3112   GetMapOfAIS().Bind(myAisEngineBlock,"b");
3113   GetMapOfAIS().Bind(myAisCrankArm,"c");
3114   GetMapOfAIS().Bind(myAisPropeller,"d");
3115
3116   myAisCylinderHead->SetMutable (Standard_True);
3117   myAisEngineBlock ->SetMutable (Standard_True);
3118   myAisCrankArm    ->SetMutable (Standard_True);
3119   myAisPropeller   ->SetMutable (Standard_True);
3120
3121   TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
3122   TheAISContext()->SetColor (myAisEngineBlock,  Quantity_NOC_RED);
3123   TheAISContext()->SetColor (myAisPropeller,    Quantity_NOC_GREEN);
3124
3125   TheAISContext()->Display (myAisCylinderHead, Standard_False);
3126   TheAISContext()->Display (myAisEngineBlock,  Standard_False);
3127   TheAISContext()->Display (myAisCrankArm,     Standard_False);
3128   TheAISContext()->Display (myAisPropeller,    Standard_False);
3129
3130   TheAISContext()->Deactivate(myAisCylinderHead);
3131   TheAISContext()->Deactivate(myAisEngineBlock );
3132   TheAISContext()->Deactivate(myAisCrankArm    );
3133   TheAISContext()->Deactivate(myAisPropeller   );
3134
3135   // Boucle de mouvement
3136   for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
3137
3138     angleA = thread*myAngle*M_PI/180;
3139     X = Sin(angleA)*3/8;
3140     angleB = atan(X / Sqrt(-X * X + 1));
3141     Standard_Real decal(25*0.6);
3142
3143
3144     //Build a transformation on the display
3145     gp_Trsf aPropellerTrsf;
3146     aPropellerTrsf.SetRotation(Ax1,angleA);
3147     TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
3148
3149     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));
3150     gp_Trsf aCrankArmTrsf;
3151     aCrankArmTrsf.SetTransformation(   base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
3152     TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
3153
3154     TheAISContext()->UpdateCurrentViewer();
3155   }
3156
3157   TopoDS_Shape myNewCrankArm  =myAisCrankArm ->Shape().Located( myAisCrankArm ->Location() );
3158   TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Location() );
3159
3160   myAisCrankArm ->ResetLocation();
3161   myAisPropeller->ResetLocation();
3162
3163   myAisCrankArm  -> Set(myNewCrankArm );
3164   myAisPropeller -> Set(myNewPropeller);
3165
3166   TheAISContext()->Activate(myAisCylinderHead,0);
3167   TheAISContext()->Activate(myAisEngineBlock,0 );
3168   TheAISContext()->Activate(myAisCrankArm ,0   );
3169   TheAISContext()->Activate(myAisPropeller ,0  );
3170
3171   myTimer.Stop();
3172   myTimer.Show();
3173   myTimer.Start();
3174
3175   TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
3176   TheAISContext()->Redisplay(myAisPropeller,Standard_False);
3177
3178   TheAISContext()->UpdateCurrentViewer();
3179   a3DView()->Redraw();
3180
3181   myTimer.Stop();
3182   myTimer.Show();
3183
3184   return 0;
3185
3186 }
3187
3188 //==============================================================================
3189 //function : VShading
3190 //purpose  : Sharpen or roughten the quality of the shading
3191 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
3192 //==============================================================================
3193 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
3194 {
3195   Standard_Real    myDevCoef;
3196   Handle(AIS_InteractiveObject) TheAisIO;
3197
3198   // Verifications
3199   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
3200
3201   if (TheAISContext()->HasOpenedContext())
3202     TheAISContext()->CloseLocalContext();
3203
3204   if (argc < 3) {
3205     myDevCoef  = 0.0008;
3206   } else {
3207     myDevCoef  =Draw::Atof(argv[2]);
3208   }
3209
3210   TCollection_AsciiString name=argv[1];
3211   if (GetMapOfAIS().IsBound2(name ))
3212     TheAisIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
3213   if (TheAisIO.IsNull())
3214     TheAisIO=GetAISShapeFromName((const char *)name.ToCString());
3215
3216   if (HaveToSet)
3217     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
3218   else
3219     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
3220
3221   TheAISContext()->Redisplay(TheAisIO);
3222   return 0;
3223 }
3224 //==============================================================================
3225 //function : HaveMode
3226 //use      : VActivatedModes
3227 //==============================================================================
3228 #include <TColStd_ListIteratorOfListOfInteger.hxx>
3229
3230 Standard_Boolean  HaveMode(const Handle(AIS_InteractiveObject)& TheAisIO,const Standard_Integer mode  )
3231 {
3232   TColStd_ListOfInteger List;
3233   TheAISContext()->ActivatedModes (TheAisIO,List);
3234   TColStd_ListIteratorOfListOfInteger it;
3235   Standard_Boolean Found=Standard_False;
3236   for (it.Initialize(List); it.More()&&!Found; it.Next() ){
3237     if (it.Value()==mode ) Found=Standard_True;
3238   }
3239   return Found;
3240 }
3241
3242
3243
3244 //==============================================================================
3245 //function : VActivatedMode
3246 //author   : ege
3247 //purpose  : permet d'attribuer a chacune des shapes un mode d'activation
3248 //           (edges,vertex...)qui lui est propre et le mode de selection standard.
3249 //           La fonction s'applique aux shapes selectionnees(current ou selected dans le viewer)
3250 //             Dans le cas ou on veut psser la shape en argument, la fonction n'autorise
3251 //           qu'un nom et qu'un mode.
3252 //Draw arg : vsetam  [ShapeName] mode(0,1,2,3,4,5,6,7)
3253 //==============================================================================
3254 #include <AIS_ListIteratorOfListOfInteractive.hxx>
3255
3256 static int VActivatedMode (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3257
3258 {
3259   Standard_Boolean ThereIsName = Standard_False ;
3260
3261   if(!a3DView().IsNull()){
3262
3263     const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetam") == 0);
3264     // verification des arguments
3265     if (HaveToSet) {
3266       if (argc<2||argc>3) { di<<" Syntaxe error"<<"\n";return 1;}
3267       ThereIsName = (argc == 3);
3268     }
3269     else {
3270       // vunsetam
3271       if (argc>1) {di<<" Syntaxe error"<<"\n";return 1;}
3272       else {
3273         di<<" R.A.Z de tous les modes de selecion"<<"\n";
3274         di<<" Fermeture du Context local"<<"\n";
3275         if (TheAISContext()->HasOpenedContext())
3276           TheAISContext()->CloseLocalContext();
3277       }
3278     }
3279
3280     // IL n'y a aps de nom de shape passe en argument
3281     if (HaveToSet && !ThereIsName){
3282       Standard_Integer aMode=Draw::Atoi(argv [1]);
3283
3284       const char *cmode="???";
3285       switch (aMode) {
3286       case 0: cmode = "Shape"; break;
3287       case 1: cmode = "Vertex"; break;
3288       case 2: cmode = "Edge"; break;
3289       case 3: cmode = "Wire"; break;
3290       case 4: cmode = "Face"; break;
3291       case 5: cmode = "Shell"; break;
3292       case 6: cmode = "Solid"; break;
3293       case 7: cmode = "Compound"; break;
3294       }
3295
3296       if( !TheAISContext()->HasOpenedContext() ) {
3297         // il n'y a pas de Context local d'ouvert
3298         // on en ouvre un et on charge toutes les shapes displayees
3299         // on load tous les objets displayees et on Activate les objets de la liste
3300         AIS_ListOfInteractive ListOfIO;
3301         // on sauve dans une AISListOfInteractive tous les objets currents
3302         if (TheAISContext()->NbCurrents()>0 ){
3303           TheAISContext()->UnhilightCurrents(Standard_False);
3304
3305           for (TheAISContext()->InitCurrent(); TheAISContext()->MoreCurrent(); TheAISContext()->NextCurrent() ){
3306             ListOfIO.Append(TheAISContext()->Current() );
3307           }
3308         }
3309
3310         TheAISContext()->OpenLocalContext(Standard_False);
3311         ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3312           it (GetMapOfAIS());
3313         while(it.More()){
3314           Handle(AIS_InteractiveObject) aIO =
3315             Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3316           if (!aIO.IsNull())
3317             TheAISContext()->Load(aIO,0,Standard_False);
3318           it.Next();
3319         }
3320         // traitement des objets qui etaient currents dans le Contexte global
3321         if (!ListOfIO.IsEmpty() ) {
3322           // il y avait des objets currents
3323           AIS_ListIteratorOfListOfInteractive iter;
3324           for (iter.Initialize(ListOfIO); iter.More() ; iter.Next() ) {
3325             Handle(AIS_InteractiveObject) aIO=iter.Value();
3326             TheAISContext()->Activate(aIO,aMode);
3327             di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString()  <<"\n";
3328           }
3329         }
3330         else {
3331           // On applique le mode a tous les objets displayes
3332           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3333             it2 (GetMapOfAIS());
3334           while(it2.More()){
3335             Handle(AIS_InteractiveObject) aIO =
3336               Handle(AIS_InteractiveObject)::DownCast(it2.Key1());
3337             if (!aIO.IsNull()) {
3338               di<<" Mode: "<<cmode<<" ON pour "<<it2.Key2().ToCString() <<"\n";
3339               TheAISContext()->Activate(aIO,aMode);
3340             }
3341             it2.Next();
3342           }
3343         }
3344
3345       }
3346
3347       else {
3348         // un Context local est deja ouvert
3349         // Traitement des objets du Context local
3350         if (TheAISContext()->NbSelected()>0 ){
3351           TheAISContext()->UnhilightSelected(Standard_False);
3352           // il y a des objets selected,on les parcourt
3353           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
3354             Handle(AIS_InteractiveObject) aIO=TheAISContext()->Interactive();
3355
3356
3357             if (HaveMode(aIO,aMode) ) {
3358               di<<" Mode: "<<cmode<<" OFF pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3359               TheAISContext()->Deactivate(aIO,aMode);
3360             }
3361             else{
3362               di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3363               TheAISContext()->Activate(aIO,aMode);
3364             }
3365
3366           }
3367         }
3368         else{
3369           // il n'y a pas d'objets selected
3370           // tous les objets diplayes sont traites
3371           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3372             it (GetMapOfAIS());
3373           while(it.More()){
3374             Handle(AIS_InteractiveObject) aIO =
3375               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3376             if (!aIO.IsNull()) {
3377               if (HaveMode(aIO,aMode) ) {
3378                 di<<" Mode: "<<cmode<<" OFF pour "
3379                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3380                 TheAISContext()->Deactivate(aIO,aMode);
3381               }
3382               else{
3383                 di<<" Mode: "<<cmode<<" ON pour"
3384                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3385                 TheAISContext()->Activate(aIO,aMode);
3386               }
3387             }
3388             it.Next();
3389           }
3390         }
3391       }
3392     }
3393     else if (HaveToSet && ThereIsName){
3394       Standard_Integer aMode=Draw::Atoi(argv [2]);
3395       Handle(AIS_InteractiveObject) aIO =
3396         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
3397
3398       if (!aIO.IsNull()) {
3399         const char *cmode="???";
3400
3401         switch (aMode) {
3402         case 0: cmode = "Shape"; break;
3403         case 1: cmode = "Vertex"; break;
3404         case 2: cmode = "Edge"; break;
3405         case 3: cmode = "Wire"; break;
3406         case 4: cmode = "Face"; break;
3407         case 5: cmode = "Shell"; break;
3408         case 6: cmode = "Solid"; break;
3409         case 7: cmode = "Compound"; break;
3410         }
3411
3412         if( !TheAISContext()->HasOpenedContext() ) {
3413           TheAISContext()->OpenLocalContext(Standard_False);
3414           // On charge tous les objets de la map
3415           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it (GetMapOfAIS());
3416           while(it.More()){
3417             Handle(AIS_InteractiveObject) aShape=
3418               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3419             if (!aShape.IsNull())
3420               TheAISContext()->Load(aShape,0,Standard_False);
3421             it.Next();
3422           }
3423           TheAISContext()->Activate(aIO,aMode);
3424           di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
3425         }
3426
3427         else {
3428           // un Context local est deja ouvert
3429           if (HaveMode(aIO,aMode) ) {
3430             di<<" Mode: "<<cmode<<" OFF pour "<<argv[1]<<"\n";
3431             TheAISContext()->Deactivate(aIO,aMode);
3432           }
3433           else{
3434             di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
3435             TheAISContext()->Activate(aIO,aMode);
3436           }
3437         }
3438       }
3439     }
3440   }
3441   return 0;
3442 }
3443
3444 //! Auxiliary method to print Interactive Object information
3445 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
3446                      const Handle(Standard_Transient)&                     theObject,
3447                      Draw_Interpretor&                                     theDI)
3448 {
3449   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theObject);
3450   if (anObj.IsNull())
3451   {
3452     theDI << theObject->DynamicType()->Name() << " is not AIS presentation\n";
3453     return;
3454   }
3455
3456   theDI << (TheAISContext()->IsDisplayed  (anObj) ? "Displayed"  : "Hidden   ")
3457         << (TheAISContext()->IsSelected   (anObj) ? " Selected" : "         ")
3458         << (theDetected.Contains (anObj)          ? " Detected" : "         ")
3459         << " Type: ";
3460   if (anObj->Type() == AIS_KOI_Datum)
3461   {
3462     // AIS_Datum
3463     if      (anObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
3464     else if (anObj->Signature() == 2) { theDI << " AIS_Axis"; }
3465     else if (anObj->Signature() == 6) { theDI << " AIS_Circle"; }
3466     else if (anObj->Signature() == 5) { theDI << " AIS_Line"; }
3467     else if (anObj->Signature() == 7) { theDI << " AIS_Plane"; }
3468     else if (anObj->Signature() == 1) { theDI << " AIS_Point"; }
3469     else if (anObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
3470   }
3471   // AIS_Shape
3472   else if (anObj->Type()      == AIS_KOI_Shape
3473         && anObj->Signature() == 0)
3474   {
3475     theDI << " AIS_Shape";
3476   }
3477   else if (anObj->Type() == AIS_KOI_Relation)
3478   {
3479     // AIS_Dimention and AIS_Relation
3480     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (anObj);
3481     switch (aRelation->KindOfDimension())
3482     {
3483       case AIS_KOD_PLANEANGLE:     theDI << " AIS_AngleDimension"; break;
3484       case AIS_KOD_LENGTH:         theDI << " AIS_Chamf2/3dDimension/AIS_LengthDimension"; break;
3485       case AIS_KOD_DIAMETER:       theDI << " AIS_DiameterDimension"; break;
3486       case AIS_KOD_ELLIPSERADIUS:  theDI << " AIS_EllipseRadiusDimension"; break;
3487       //case AIS_KOD_FILLETRADIUS:   theDI << " AIS_FilletRadiusDimension "; break;
3488       case AIS_KOD_OFFSET:         theDI << " AIS_OffsetDimension"; break;
3489       case AIS_KOD_RADIUS:         theDI << " AIS_RadiusDimension"; break;
3490       default:                     theDI << " UNKNOWN dimension"; break;
3491     }
3492   }
3493   else
3494   {
3495     theDI << " UserPrs";
3496   }
3497   theDI << " (" << theObject->DynamicType()->Name() << ")";
3498 }
3499
3500 //! Print information about locally selected sub-shapes
3501 static void localCtxInfo (Draw_Interpretor& theDI)
3502 {
3503   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
3504   if (!aCtx->HasOpenedContext())
3505   {
3506     return;
3507   }
3508
3509   TCollection_AsciiString aPrevName;
3510   Handle(AIS_LocalContext) aCtxLoc = aCtx->LocalContext();
3511   for (aCtxLoc->InitSelected(); aCtxLoc->MoreSelected(); aCtxLoc->NextSelected())
3512   {
3513     const TopoDS_Shape      aSubShape = aCtxLoc->SelectedShape();
3514     const Handle(AIS_Shape) aShapeIO  = Handle(AIS_Shape)::DownCast (aCtxLoc->SelectedInteractive());
3515     if (aSubShape.IsNull()
3516       || aShapeIO.IsNull()
3517       || !GetMapOfAIS().IsBound1 (aShapeIO))
3518     {
3519       continue;
3520     }
3521
3522     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
3523     TopTools_MapOfShape aFilter;
3524     Standard_Integer    aNumber = 0;
3525     const TopoDS_Shape  aShape  = aShapeIO->Shape();
3526     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
3527          anIter.More(); anIter.Next())
3528     {
3529       if (!aFilter.Add (anIter.Current()))
3530       {
3531         continue; // filter duplicates
3532       }
3533
3534       ++aNumber;
3535       if (!anIter.Current().IsSame (aSubShape))
3536       {
3537         continue;
3538       }
3539
3540       Standard_CString aShapeName = NULL;
3541       switch (aSubShape.ShapeType())
3542       {
3543         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
3544         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
3545         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
3546         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
3547         case TopAbs_FACE:      aShapeName = "     Face"; break;
3548         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
3549         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
3550         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
3551         default:
3552         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
3553       }
3554
3555       if (aParentName != aPrevName)
3556       {
3557         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
3558         aPrevName = aParentName;
3559       }
3560       theDI << "  " << aShapeName << " #" << aNumber << "\n";
3561       break;
3562     }
3563   }
3564 }
3565
3566 //==============================================================================
3567 //function : VState
3568 //purpose  :
3569 //Draw arg : vstate [nameA] ... [nameN]
3570 //==============================================================================
3571 static Standard_Integer VState (Draw_Interpretor& theDI,
3572                                 Standard_Integer  theArgNb,
3573                                 Standard_CString* theArgVec)
3574 {
3575   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
3576   if (aCtx.IsNull())
3577   {
3578     std::cerr << "Error: No opened viewer!\n";
3579     return 1;
3580   }
3581
3582   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
3583   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
3584   {
3585     aDetected.Add (aCtx->DetectedCurrentObject());
3586   }
3587
3588   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
3589   if (theArgNb >= 2
3590    && !toShowAll)
3591   {
3592     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3593     {
3594       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
3595       if (!GetMapOfAIS().IsBound2 (anObjName))
3596       {
3597         theDI << anObjName << " doesn't exist!\n";
3598         continue;
3599       }
3600
3601       const Handle(Standard_Transient) anObjTrans = GetMapOfAIS().Find2 (anObjName);
3602       TCollection_AsciiString aName = anObjName;
3603       aName.LeftJustify (20, ' ');
3604       theDI << "  " << aName << " ";
3605       objInfo (aDetected, anObjTrans, theDI);
3606       theDI << "\n";
3607     }
3608     return 0;
3609   }
3610
3611   if (aCtx->NbCurrents() > 0
3612    && !toShowAll)
3613   {
3614     for (aCtx->InitCurrent(); aCtx->MoreCurrent(); aCtx->NextCurrent())
3615     {
3616       Handle(AIS_InteractiveObject) anObj = aCtx->Current();
3617       TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
3618       aName.LeftJustify (20, ' ');
3619       theDI << aName << " ";
3620       objInfo (aDetected, anObj, theDI);
3621       theDI << "\n";
3622     }
3623     return 0;
3624   }
3625
3626   theDI << "Neutral-point state:\n";
3627   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
3628        anObjIter.More(); anObjIter.Next())
3629   {
3630     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anObjIter.Key1());
3631     if (anObj.IsNull())
3632     {
3633       continue;
3634     }
3635
3636     TCollection_AsciiString aName = anObjIter.Key2();
3637     aName.LeftJustify (20, ' ');
3638     theDI << "  " << aName << " ";
3639     objInfo (aDetected, anObj, theDI);
3640     theDI << "\n";
3641   }
3642   localCtxInfo (theDI);
3643   return 0;
3644 }
3645
3646 //=======================================================================
3647 //function : PickObjects
3648 //purpose  :
3649 //=======================================================================
3650 Standard_Boolean  ViewerTest::PickObjects(Handle(TColStd_HArray1OfTransient)& arr,
3651                                           const AIS_KindOfInteractive TheType,
3652                                           const Standard_Integer TheSignature,
3653                                           const Standard_Integer MaxPick)
3654 {
3655   Handle(AIS_InteractiveObject) IO;
3656   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
3657
3658   // step 1: prepare the data
3659   if(curindex !=0){
3660     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
3661     TheAISContext()->AddFilter(F1);
3662   }
3663
3664   // step 2 : wait for the selection...
3665 //  Standard_Boolean IsGood (Standard_False);
3666 //  Standard_Integer NbPick(0);
3667   Standard_Boolean NbPickGood (0),NbToReach(arr->Length());
3668   Standard_Integer NbPickFail(0);
3669   Standard_Integer argccc = 5;
3670   const char *bufff[] = { "A", "B", "C","D", "E" };
3671   const char **argvvv = (const char **) bufff;
3672
3673
3674   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
3675     while(ViewerMainLoop(argccc,argvvv)){}
3676     Standard_Integer NbStored = TheAISContext()->NbSelected();
3677     if((unsigned int ) NbStored != NbPickGood)
3678       NbPickGood= NbStored;
3679     else
3680       NbPickFail++;
3681     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<endl;
3682   }
3683
3684   // step3 get result.
3685
3686   if((unsigned int ) NbPickFail >= NbToReach) return Standard_False;
3687
3688   Standard_Integer i(0);
3689   for(TheAISContext()->InitSelected();
3690       TheAISContext()->MoreSelected();
3691       TheAISContext()->NextSelected()){
3692     i++;
3693     Handle(AIS_InteractiveObject) IO2 = TheAISContext()->SelectedInteractive();
3694     arr->SetValue(i,IO2);
3695   }
3696
3697
3698   if(curindex>0)
3699     TheAISContext()->CloseLocalContext(curindex);
3700
3701   return Standard_True;
3702 }
3703
3704
3705 //=======================================================================
3706 //function : PickObject
3707 //purpose  :
3708 //=======================================================================
3709 Handle(AIS_InteractiveObject) ViewerTest::PickObject(const AIS_KindOfInteractive TheType,
3710                                                      const Standard_Integer TheSignature,
3711                                                      const Standard_Integer MaxPick)
3712 {
3713   Handle(AIS_InteractiveObject) IO;
3714   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
3715
3716   // step 1: prepare the data
3717
3718   if(curindex !=0){
3719     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
3720     TheAISContext()->AddFilter(F1);
3721   }
3722
3723   // step 2 : wait for the selection...
3724   Standard_Boolean IsGood (Standard_False);
3725   Standard_Integer NbPick(0);
3726   Standard_Integer argccc = 5;
3727   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
3728   const char **argvvv = (const char **) bufff;
3729
3730
3731   while(!IsGood && NbPick<= MaxPick){
3732     while(ViewerMainLoop(argccc,argvvv)){}
3733     IsGood = (TheAISContext()->NbSelected()>0) ;
3734     NbPick++;
3735     cout<<"Nb Pick :"<<NbPick<<endl;
3736   }
3737
3738
3739   // step3 get result.
3740   if(IsGood){
3741     TheAISContext()->InitSelected();
3742     IO = TheAISContext()->SelectedInteractive();
3743   }
3744
3745   if(curindex!=0)
3746     TheAISContext()->CloseLocalContext(curindex);
3747   return IO;
3748 }
3749
3750 //=======================================================================
3751 //function : PickShape
3752 //purpose  : First Activate the rightmode + Put Filters to be able to
3753 //           pick objets that are of type <TheType>...
3754 //=======================================================================
3755
3756 TopoDS_Shape ViewerTest::PickShape(const TopAbs_ShapeEnum TheType,
3757                                    const Standard_Integer MaxPick)
3758 {
3759
3760   // step 1: prepare the data
3761
3762   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
3763   TopoDS_Shape result;
3764
3765   if(TheType==TopAbs_SHAPE){
3766     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
3767     TheAISContext()->AddFilter(F1);
3768   }
3769   else{
3770     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
3771     TheAISContext()->AddFilter(TF);
3772     TheAISContext()->ActivateStandardMode(TheType);
3773
3774   }
3775
3776
3777   // step 2 : wait for the selection...
3778   Standard_Boolean NoShape (Standard_True);
3779   Standard_Integer NbPick(0);
3780   Standard_Integer argccc = 5;
3781   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
3782   const char **argvvv = (const char **) bufff;
3783
3784
3785   while(NoShape && NbPick<= MaxPick){
3786     while(ViewerMainLoop(argccc,argvvv)){}
3787     NoShape = (TheAISContext()->NbSelected()==0) ;
3788     NbPick++;
3789     cout<<"Nb Pick :"<<NbPick<<endl;
3790   }
3791
3792   // step3 get result.
3793
3794   if(!NoShape){
3795
3796     TheAISContext()->InitSelected();
3797     if(TheAISContext()->HasSelectedShape())
3798       result = TheAISContext()->SelectedShape();
3799     else{
3800       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
3801       result = (*((Handle(AIS_Shape)*) &IO))->Shape();
3802     }
3803   }
3804
3805   if(curindex>0)
3806     TheAISContext()->CloseLocalContext(curindex);
3807
3808   return result;
3809 }
3810
3811
3812 //=======================================================================
3813 //function : PickShapes
3814 //purpose  :
3815 //=======================================================================
3816 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum TheType,
3817                                          Handle(TopTools_HArray1OfShape)& thearr,
3818                                          const Standard_Integer MaxPick)
3819 {
3820
3821   Standard_Integer Taille = thearr->Length();
3822   if(Taille>1)
3823     cout<<" WARNING : Pick with Shift+ MB1 for Selection of more than 1 object"<<"\n";
3824
3825   // step 1: prepare the data
3826   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
3827   if(TheType==TopAbs_SHAPE){
3828     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
3829     TheAISContext()->AddFilter(F1);
3830   }
3831   else{
3832     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
3833     TheAISContext()->AddFilter(TF);
3834     TheAISContext()->ActivateStandardMode(TheType);
3835
3836   }
3837
3838   // step 2 : wait for the selection...
3839
3840   Standard_Boolean NbPickGood (0),NbToReach(thearr->Length());
3841   Standard_Integer NbPickFail(0);
3842   Standard_Integer argccc = 5;
3843   const char *bufff[] = { "A", "B", "C","D", "E" };
3844   const char **argvvv = (const char **) bufff;
3845
3846
3847   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
3848     while(ViewerMainLoop(argccc,argvvv)){}
3849     Standard_Integer NbStored = TheAISContext()->NbSelected();
3850     if((unsigned int ) NbStored != NbPickGood)
3851       NbPickGood= NbStored;
3852     else
3853       NbPickFail++;
3854     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<"\n";
3855   }
3856
3857   // step3 get result.
3858
3859   if((unsigned int ) NbPickFail >= NbToReach) return Standard_False;
3860
3861   Standard_Integer i(0);
3862   for(TheAISContext()->InitSelected();TheAISContext()->MoreSelected();TheAISContext()->NextSelected()){
3863     i++;
3864     if(TheAISContext()->HasSelectedShape())
3865       thearr->SetValue(i,TheAISContext()->SelectedShape());
3866     else{
3867       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
3868       thearr->SetValue(i,(*((Handle(AIS_Shape)*) &IO))->Shape());
3869     }
3870   }
3871
3872   TheAISContext()->CloseLocalContext(curindex);
3873   return Standard_True;
3874 }
3875
3876
3877 //=======================================================================
3878 //function : VPickShape
3879 //purpose  :
3880 //=======================================================================
3881 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3882 {
3883   TopoDS_Shape PickSh;
3884   TopAbs_ShapeEnum theType = TopAbs_COMPOUND;
3885
3886   if(argc==1)
3887     theType = TopAbs_SHAPE;
3888   else{
3889     if(!strcasecmp(argv[1],"V" )) theType = TopAbs_VERTEX;
3890     else if (!strcasecmp(argv[1],"E" )) theType = TopAbs_EDGE;
3891     else if (!strcasecmp(argv[1],"W" )) theType = TopAbs_WIRE;
3892     else if (!strcasecmp(argv[1],"F" )) theType = TopAbs_FACE;
3893     else if(!strcasecmp(argv[1],"SHAPE" )) theType = TopAbs_SHAPE;
3894     else if (!strcasecmp(argv[1],"SHELL" )) theType = TopAbs_SHELL;
3895     else if (!strcasecmp(argv[1],"SOLID" )) theType = TopAbs_SOLID;
3896   }
3897
3898   static Standard_Integer nbOfSub[8]={0,0,0,0,0,0,0,0};
3899   static TCollection_AsciiString nameType[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
3900
3901   TCollection_AsciiString name;
3902
3903
3904   Standard_Integer NbToPick = argc>2 ? argc-2 : 1;
3905   if(NbToPick==1){
3906     PickSh = ViewerTest::PickShape(theType);
3907
3908     if(PickSh.IsNull())
3909       return 1;
3910     if(argc>2){
3911       name += argv[2];
3912     }
3913     else{
3914
3915       if(!PickSh.IsNull()){
3916         nbOfSub[Standard_Integer(theType)]++;
3917         name += "Picked_";
3918         name += nameType[Standard_Integer(theType)];
3919         TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
3920         name +="_";
3921         name+=indxstring;
3922       }
3923     }
3924     // si on avait une petite methode pour voir si la shape
3925     // est deja dans la Double map, ca eviterait de creer....
3926     DBRep::Set(name.ToCString(),PickSh);
3927
3928     Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
3929     GetMapOfAIS().Bind(newsh, name);
3930     TheAISContext()->Display(newsh);
3931     di<<"Nom de la shape pickee : "<<name.ToCString()<<"\n";
3932   }
3933
3934   // Plusieurs objets a picker, vite vite vite....
3935   //
3936   else{
3937     Standard_Boolean autonaming = !strcasecmp(argv[2],".");
3938     Handle(TopTools_HArray1OfShape) arr = new TopTools_HArray1OfShape(1,NbToPick);
3939     if(ViewerTest::PickShapes(theType,arr)){
3940       for(Standard_Integer i=1;i<=NbToPick;i++){
3941         PickSh = arr->Value(i);
3942         if(!PickSh.IsNull()){
3943           if(autonaming){
3944             nbOfSub[Standard_Integer(theType)]++;
3945             name.Clear();
3946             name += "Picked_";
3947             name += nameType[Standard_Integer(theType)];
3948             TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
3949             name +="_";
3950             name+=indxstring;
3951           }
3952         }
3953         else
3954           name = argv[1+i];
3955
3956         DBRep::Set(name.ToCString(),PickSh);
3957         Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
3958         GetMapOfAIS().Bind(newsh, name);
3959         di<<"display of picke shape #"<<i<<" - nom : "<<name.ToCString()<<"\n";
3960         TheAISContext()->Display(newsh);
3961
3962       }
3963     }
3964   }
3965   return 0;
3966 }
3967
3968 //=======================================================================
3969 //function : list of known objects
3970 //purpose  :
3971 //=======================================================================
3972 static int VIOTypes( Draw_Interpretor& di, Standard_Integer , const char** )
3973 {
3974   //                             1234567890         12345678901234567         123456789
3975   TCollection_AsciiString Colum [3]={"Standard Types","Type Of Object","Signature"};
3976   TCollection_AsciiString BlankLine(64,'_');
3977   Standard_Integer i ;
3978
3979   di<<"/n"<<BlankLine.ToCString()<<"\n";
3980
3981   for( i =0;i<=2;i++)
3982     Colum[i].Center(20,' ');
3983   for(i=0;i<=2;i++)
3984     di<<"|"<<Colum[i].ToCString();
3985   di<<"|"<<"\n";
3986
3987   di<<BlankLine.ToCString()<<"\n";
3988
3989   //  TCollection_AsciiString thetypes[5]={"Datum","Shape","Object","Relation","None"};
3990   const char ** names = GetTypeNames();
3991
3992   TCollection_AsciiString curstring;
3993   TCollection_AsciiString curcolum[3];
3994
3995
3996   // les objets de type Datum..
3997   curcolum[1]+="Datum";
3998   for(i =0;i<=6;i++){
3999     curcolum[0].Clear();
4000     curcolum[0] += names[i];
4001
4002     curcolum[2].Clear();
4003     curcolum[2]+=TCollection_AsciiString(i+1);
4004
4005     for(Standard_Integer j =0;j<=2;j++){
4006       curcolum[j].Center(20,' ');
4007       di<<"|"<<curcolum[j].ToCString();
4008     }
4009     di<<"|"<<"\n";
4010   }
4011   di<<BlankLine.ToCString()<<"\n";
4012
4013   // les objets de type shape
4014   curcolum[1].Clear();
4015   curcolum[1]+="Shape";
4016   curcolum[1].Center(20,' ');
4017
4018   for(i=0;i<=2;i++){
4019     curcolum[0].Clear();
4020     curcolum[0] += names[7+i];
4021     curcolum[2].Clear();
4022     curcolum[2]+=TCollection_AsciiString(i);
4023
4024     for(Standard_Integer j =0;j<=2;j++){
4025       curcolum[j].Center(20,' ');
4026       di<<"|"<<curcolum[j].ToCString();
4027     }
4028     di<<"|"<<"\n";
4029   }
4030   di<<BlankLine.ToCString()<<"\n";
4031   // les IO de type objet...
4032   curcolum[1].Clear();
4033   curcolum[1]+="Object";
4034   curcolum[1].Center(20,' ');
4035   for(i=0;i<=1;i++){
4036     curcolum[0].Clear();
4037     curcolum[0] += names[10+i];
4038     curcolum[2].Clear();
4039     curcolum[2]+=TCollection_AsciiString(i);
4040
4041     for(Standard_Integer j =0;j<=2;j++){
4042       curcolum[j].Center(20,' ');
4043       di<<"|"<<curcolum[j].ToCString();
4044     }
4045     di<<"|"<<"\n";
4046   }
4047   di<<BlankLine.ToCString()<<"\n";
4048   // les contraintes et dimensions.
4049   // pour l'instant on separe juste contraintes et dimensions...
4050   // plus tard, on detaillera toutes les sortes...
4051   curcolum[1].Clear();
4052   curcolum[1]+="Relation";
4053   curcolum[1].Center(20,' ');
4054   for(i=0;i<=1;i++){
4055     curcolum[0].Clear();
4056     curcolum[0] += names[12+i];
4057     curcolum[2].Clear();
4058     curcolum[2]+=TCollection_AsciiString(i);
4059
4060     for(Standard_Integer j =0;j<=2;j++){
4061       curcolum[j].Center(20,' ');
4062       di<<"|"<<curcolum[j].ToCString();
4063     }
4064     di<<"|"<<"\n";
4065   }
4066   di<<BlankLine.ToCString()<<"\n";
4067
4068
4069   return 0;
4070 }
4071
4072
4073 static int VEraseType( Draw_Interpretor& , Standard_Integer argc, const char** argv)
4074 {
4075   if(argc!=2) return 1;
4076
4077   AIS_KindOfInteractive TheType;
4078   Standard_Integer TheSign(-1);
4079   GetTypeAndSignfromString(argv[1],TheType,TheSign);
4080
4081
4082   AIS_ListOfInteractive LIO;
4083
4084   // en attendant l'amelioration ais pour les dimensions...
4085   //
4086   Standard_Integer dimension_status(-1);
4087   if(TheType==AIS_KOI_Relation){
4088     dimension_status = TheSign ==1 ? 1 : 0;
4089     TheSign=-1;
4090   }
4091
4092   TheAISContext()->DisplayedObjects(TheType,TheSign,LIO);
4093   Handle(AIS_InteractiveObject) curio;
4094   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
4095     curio  = it.Value();
4096
4097     if(dimension_status == -1)
4098       TheAISContext()->Erase(curio,Standard_False);
4099     else {
4100       AIS_KindOfDimension KOD = (*((Handle(AIS_Relation)*)&curio))->KindOfDimension();
4101       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
4102           (dimension_status==1 && KOD != AIS_KOD_NONE))
4103         TheAISContext()->Erase(curio,Standard_False);
4104     }
4105   }
4106   TheAISContext()->UpdateCurrentViewer();
4107   return 0;
4108 }
4109 static int VDisplayType(Draw_Interpretor& , Standard_Integer argc, const char** argv)
4110 {
4111   if(argc!=2) return 1;
4112
4113   AIS_KindOfInteractive TheType;
4114   Standard_Integer TheSign(-1);
4115   GetTypeAndSignfromString(argv[1],TheType,TheSign);
4116
4117   // en attendant l'amelioration ais pour les dimensions...
4118   //
4119   Standard_Integer dimension_status(-1);
4120   if(TheType==AIS_KOI_Relation){
4121     dimension_status = TheSign ==1 ? 1 : 0;
4122     TheSign=-1;
4123   }
4124
4125   AIS_ListOfInteractive LIO;
4126   TheAISContext()->ObjectsInside(LIO,TheType,TheSign);
4127   Handle(AIS_InteractiveObject) curio;
4128   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
4129     curio  = it.Value();
4130     if(dimension_status == -1)
4131       TheAISContext()->Display(curio,Standard_False);
4132     else {
4133       AIS_KindOfDimension KOD = (*((Handle(AIS_Relation)*)&curio))->KindOfDimension();
4134       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
4135           (dimension_status==1 && KOD != AIS_KOD_NONE))
4136         TheAISContext()->Display(curio,Standard_False);
4137     }
4138
4139   }
4140
4141   TheAISContext()->UpdateCurrentViewer();
4142   return 0;
4143 }
4144
4145 //==============================================================================
4146 //function : VSetTransMode
4147 //purpose  :
4148 //Draw arg : vsettransmode shape flag1 [flag2] [flag3] [X Y Z]
4149 //==============================================================================
4150
4151 static int VSetTransMode ( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4152   // Verification des arguments
4153   if ( a3DView().IsNull() ) {
4154     ViewerTest::ViewerInit();
4155     di << "La commande vinit n'a pas ete appele avant" << "\n";
4156   }
4157
4158   if ( argc < 3 || argc > 8 ) {
4159     di << argv[0] << " Invalid number of arguments" << "\n";
4160     return 1;
4161   }
4162
4163   TCollection_AsciiString shapeName;
4164   shapeName = argv[1];
4165   Standard_Integer persFlag1 = Draw::Atoi(argv[2]);
4166   Standard_Integer persFlag2 = 0;
4167   Standard_Integer persFlag3 = 0;
4168   gp_Pnt origin = gp_Pnt( 0.0, 0.0, 0.0 );
4169   if ( argc == 4 || argc == 5 || argc == 7 || argc == 8 ) {
4170     persFlag2 = Draw::Atoi(argv[3]);
4171   }
4172   if ( argc == 5 || argc == 8 ) {
4173     persFlag3 = Draw::Atoi(argv[4]);
4174   }
4175   if ( argc >= 6 ) {
4176     origin.SetX( Draw::Atof(argv[argc - 3]) );
4177     origin.SetY( Draw::Atof(argv[argc - 2]) );
4178     origin.SetZ( Draw::Atof(argv[argc - 1]) );
4179   }
4180
4181   Standard_Boolean IsBound = GetMapOfAIS().IsBound2(shapeName);
4182   Handle(Standard_Transient) anObj;
4183   if ( IsBound ) {
4184     anObj = GetMapOfAIS().Find2(shapeName);
4185     if ( anObj->IsKind(STANDARD_TYPE(AIS_InteractiveObject)) ) {
4186       Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast(anObj);
4187       aShape->SetTransformPersistence( (persFlag1 | persFlag2 | persFlag3), origin );
4188       if ( persFlag1 == 0 && persFlag2 == 0 && persFlag3 == 0 ) {
4189         di << argv[0] << " All persistence modifiers were removed" << "\n";
4190       }
4191     } else {
4192       di << argv[0] << " Wrong object type" << "\n";
4193       return 1;
4194     }
4195   } else { // Create the AIS_Shape from a name
4196     const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName((const char* )shapeName.ToCString());
4197     if ( !aShape.IsNull() ) {
4198       GetMapOfAIS().Bind( aShape, shapeName );
4199       aShape->SetTransformPersistence( (persFlag1 | persFlag2 | persFlag3), origin );
4200       TheAISContext()->Display( aShape, Standard_False );
4201     } else {
4202       di << argv[0] << " Object not found" << "\n";
4203       return 1;
4204     }
4205   }
4206
4207   // Upadate the screen and redraw the view
4208   TheAISContext()->UpdateCurrentViewer();
4209   return 0;
4210 }
4211
4212 static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a)
4213 {
4214   ifstream s(a[1]);
4215   BRep_Builder builder;
4216   TopoDS_Shape shape;
4217   BRepTools::Read(shape, s, builder);
4218   DBRep::Set(a[1], shape);
4219   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
4220   Handle(AIS_Shape) ais = new AIS_Shape(shape);
4221   Ctx->Display(ais);
4222   return 0;
4223 }
4224
4225 //==============================================================================
4226 //function : ViewerTest::Commands
4227 //purpose  : Add all the viewer command in the Draw_Interpretor
4228 //==============================================================================
4229
4230 void ViewerTest::Commands(Draw_Interpretor& theCommands)
4231 {
4232   ViewerTest::ViewerCommands(theCommands);
4233   ViewerTest::RelationCommands(theCommands);
4234   ViewerTest::ObjectCommands(theCommands);
4235   ViewerTest::FilletCommands(theCommands);
4236   ViewerTest::VoxelCommands(theCommands);
4237   ViewerTest::OpenGlCommands(theCommands);
4238
4239   const char *group = "AIS_Display";
4240
4241   // display
4242   theCommands.Add("visos",
4243                   "visos [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]\n"
4244                   "\tIf last 3 optional parameters are not set prints numbers of U-, V- isolines and IsoOnPlane.\n",
4245                   __FILE__, visos, group);
4246
4247   theCommands.Add("vdisplay",
4248                   "vdisplay [-noupdate|-update] [-mutable] name1 [name2] ... [name n]"
4249       "\n\t\t: Displays named objects."
4250       "\n\t\t: Option -noupdate suppresses viewer redraw call."
4251       "\n\t\t: Option -mutable enables optimizations for mutable objects."
4252                   __FILE__,VDisplay2,group);
4253
4254   theCommands.Add ("vupdate",
4255       "vupdate name1 [name2] ... [name n]"
4256       "\n\t\t: Updates named objects in interactive context",
4257       __FILE__, VUpdate, group);
4258
4259   theCommands.Add("verase",
4260       "verase [-noupdate|-update] [name1] ...  [name n]"
4261       "\n\t\t: Erases selected or named objects."
4262       "\n\t\t: If there are no selected or named objects the whole viewer is erased.",
4263                   __FILE__, VErase, group);
4264
4265   theCommands.Add("vremove",
4266     "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ...  [name n]"
4267     "or vremove [-context] -all to remove all objects"
4268       "\n\t\t: Removes selected or named objects."
4269       "\n\t\t  If -context is in arguments, the objects are not deleted"
4270       "\n\t\t  from the map of objects and names."
4271       "\n\t\t: Option -noupdate suppresses viewer redraw call."
4272       "\n\t\t: Option -noinfo suppresses displaying the list of removed objects.",
4273       __FILE__, VRemove, group);
4274
4275   theCommands.Add("vdonly",
4276                   "vdonly [-noupdate|-update] [name1] ...  [name n]"
4277       "\n\t\t: Displays only selected or named objects",
4278                   __FILE__,VDonly2,group);
4279
4280   theCommands.Add("vdisplayall",
4281                   "Displays all erased interactive objects (see vdir and vstate)",
4282                   __FILE__,VDisplayAll,group);
4283
4284   theCommands.Add("veraseall",
4285                   "Erases all objects displayed in the viewer",
4286                   __FILE__, VErase, group);
4287
4288   theCommands.Add("verasetype",
4289                   "verasetype <Type>"
4290       "\n\t\t: Erase all the displayed objects of one given kind (see vtypes)",
4291                   __FILE__,VEraseType,group);
4292
4293   theCommands.Add("vbounding",
4294               "vbounding [-noupdate|-update] [-mode] name1 [name2 [...]]"
4295       "\n\t\t:           [-print] [-hide]"
4296       "\n\t\t: Temporarily display bounding box of specified Interactive"
4297       "\n\t\t: Objects, or print it to console if -print is specified."
4298       "\n\t\t: Already displayed box might be hidden by -hide option.",
4299                   __FILE__,VBounding,group);
4300
4301   theCommands.Add("vdisplaytype",
4302                   "vdisplaytype        : vdisplaytype <Type> <Signature> \n\t display all the objects of one given kind (see vtypes) which are stored the AISContext ",
4303                   __FILE__,VDisplayType,group);
4304
4305   theCommands.Add("vdisplaymode",
4306                   "vdispmode       : vdispmode  [name] mode(1,2,..) : no name -> on selected objects ",
4307                   __FILE__,VDispMode,group);
4308
4309   theCommands.Add("verasemode",
4310                   "verasemode      : verasemode [name] mode(1,2,..) : no name -> on selected objects",
4311                   __FILE__,VDispMode,group);
4312
4313   theCommands.Add("vsetdispmode",
4314                   "vsetdispmode [name] mode(1,2,..)"
4315       "\n\t\t: Sets display mode for all, selected or named objects.",
4316                   __FILE__,VDispMode,group);
4317
4318   theCommands.Add("vunsetdispmode",
4319                   "vunsetdispmode [name]"
4320       "\n\t\t: Unsets custom display mode for selected or named objects.",
4321                   __FILE__,VDispMode,group);
4322
4323   theCommands.Add("vdir",
4324                   "Lists all objects displayed in 3D viewer",
4325                   __FILE__,VDir,group);
4326
4327   theCommands.Add("vdump",
4328     #ifdef HAVE_FREEIMAGE
4329               "vdump <filename>.{png|bmp|jpg|gif} [rgb|rgba|depth=rgb] [mono|left|right=mono]"
4330       "\n\t\t:                                    [width Width=0 height Height=0]"
4331       "\n\t\t: Dumps content of the active view into PNG, BMP, JPEG or GIF file",
4332     #else
4333               "vdump <filename>.{ppm} [rgb|rgba|depth=rgb] [mono|left|right=mono]"
4334       "\n\t\t:                        [width Width=0 height Height=0]"
4335       "\n\t\t: Dumps content of the active view into PPM image file",
4336     #endif
4337                   __FILE__,VDump,group);
4338
4339   theCommands.Add("vsub",      "vsub 0/1 (off/on) [obj]        : Subintensity(on/off) of selected objects",
4340                   __FILE__,VSubInt,group);
4341
4342   theCommands.Add("vaspects",
4343               "vaspects [-noupdate|-update] [name1 [name2 [...]]]"
4344       "\n\t\t:          [-setcolor ColorName] [-unsetcolor]"
4345       "\n\t\t:          [-setmaterial MatName] [-unsetmaterial]"
4346       "\n\t\t:          [-settransparency Transp] [-unsettransparency]"
4347       "\n\t\t:          [-setwidth LineWidth] [-unsetwidth]"
4348       "\n\t\t:          [-subshapes subname1 [subname2 [...]]]"
4349       "\n\t\t: Manage presentation properties of all, selected or named objects."
4350       "\n\t\t: When -subshapes is specified than following properties will be"
4351       "\n\t\t: assigned to specified sub-shapes.",
4352                   __FILE__,VAspects,group);
4353
4354   theCommands.Add("vsetcolor",
4355       "vsetcolor [-noupdate|-update] [name] ColorName"
4356       "\n\t\t: Sets color for all, selected or named objects."
4357       "\n\t\t: Alias for vaspects -setcolor [name] ColorName.",
4358                   __FILE__,VAspects,group);
4359