b3a44da1493dc453001d99b6b78de7de3684105c
[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 == "-settransparancy")
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 == "-unsettransparancy"
1667           || anArg == "-unsetalpha"
1668           || anArg == "-opaque")
1669     {
1670       aChangeSet->ToSetTransparency = -1;
1671       aChangeSet->Transparency = 0.0;
1672     }
1673     else if (anArg == "-setcolor")
1674     {
1675       if (++anArgIter >= theArgNb)
1676       {
1677         std::cout << "Error: wrong syntax at " << anArg << "\n";
1678         return 1;
1679       }
1680       aChangeSet->ToSetColor = 1;
1681       aChangeSet->Color = ViewerTest::GetColorFromName (theArgVec[anArgIter]);
1682     }
1683     else if (anArg == "-unsetcolor")
1684     {
1685       aChangeSet->ToSetColor = -1;
1686       aChangeSet->Color = DEFAULT_COLOR;
1687     }
1688     else if (anArg == "-setmat"
1689           || anArg == "-setmaterial")
1690     {
1691       if (++anArgIter >= theArgNb)
1692       {
1693         std::cout << "Error: wrong syntax at " << anArg << "\n";
1694         return 1;
1695       }
1696       aChangeSet->ToSetMaterial = 1;
1697       aChangeSet->MatName  = theArgVec[anArgIter];
1698       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1699     }
1700     else if (anArg == "-unsetmat"
1701           || anArg == "-unsetmaterial")
1702     {
1703       aChangeSet->ToSetMaterial = -1;
1704       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
1705     }
1706     else if (anArg == "-subshape"
1707           || anArg == "-subshapes")
1708     {
1709       if (aNames.IsEmpty())
1710       {
1711         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
1712         return 1;
1713       }
1714
1715       aChanges.Append (ViewerTest_AspectsChangeSet());
1716       aChangeSet = &aChanges.ChangeLast();
1717
1718       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
1719       {
1720         Standard_CString aSubShapeName = theArgVec[anArgIter];
1721         if (*aSubShapeName == '-')
1722         {
1723           --anArgIter;
1724           break;
1725         }
1726
1727         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
1728         if (aSubShape.IsNull())
1729         {
1730           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
1731           return 1;
1732         }
1733         aChangeSet->SubShapes.Append (aSubShape);
1734       }
1735
1736       if (aChangeSet->SubShapes.IsEmpty())
1737       {
1738         std::cerr << "Error: empty list is specified after -subshapes!\n";
1739         return 1;
1740       }
1741     }
1742     else if (anArg == "-unset")
1743     {
1744       aChangeSet->ToSetLineWidth = -1;
1745       aChangeSet->LineWidth = 1.0;
1746       aChangeSet->ToSetTransparency = -1;
1747       aChangeSet->Transparency = 0.0;
1748       aChangeSet->ToSetColor = -1;
1749       aChangeSet->Color = DEFAULT_COLOR;
1750       aChangeSet->ToSetMaterial = -1;
1751       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
1752     }
1753     else
1754     {
1755       std::cout << "Error: wrong syntax at " << anArg << "\n";
1756       return 1;
1757     }
1758   }
1759
1760   Standard_Boolean isFirst = Standard_True;
1761   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
1762        aChangesIter.More(); aChangesIter.Next())
1763   {
1764     if (!aChangesIter.Value().Validate (!isFirst))
1765     {
1766       return 1;
1767     }
1768     isFirst = Standard_False;
1769   }
1770
1771   if (aCtx->HasOpenedContext())
1772   {
1773     aCtx->CloseLocalContext();
1774   }
1775   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
1776   {
1777     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
1778     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
1779     Handle(AIS_ColoredShape) aColoredPrs;
1780     Standard_Boolean toDisplay = Standard_False;
1781     if (aChanges.Length() > 1)
1782     {
1783       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
1784       if (aShapePrs.IsNull())
1785       {
1786         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
1787         return 1;
1788       }
1789       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
1790       if (aColoredPrs.IsNull())
1791       {
1792         aColoredPrs = new AIS_ColoredShape (aShapePrs);
1793         aCtx->Remove (aShapePrs, Standard_False);
1794         GetMapOfAIS().UnBind2 (aName);
1795         GetMapOfAIS().Bind (aColoredPrs, aName);
1796         toDisplay = Standard_True;
1797         aShapePrs = aColoredPrs;
1798         aPrs      = aColoredPrs;
1799       }
1800     }
1801
1802     if (!aPrs.IsNull())
1803     {
1804       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
1805       aChangeSet = &aChangesIter.ChangeValue();
1806       if (aChangeSet->ToSetMaterial == 1)
1807       {
1808         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
1809       }
1810       else if (aChangeSet->ToSetMaterial == -1)
1811       {
1812         aCtx->UnsetMaterial (aPrs, Standard_False);
1813       }
1814       if (aChangeSet->ToSetColor == 1)
1815       {
1816         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
1817       }
1818       else if (aChangeSet->ToSetColor == -1)
1819       {
1820         aCtx->UnsetColor (aPrs, Standard_False);
1821       }
1822       if (aChangeSet->ToSetTransparency == 1)
1823       {
1824         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
1825       }
1826       else if (aChangeSet->ToSetTransparency == -1)
1827       {
1828         aCtx->UnsetTransparency (aPrs, Standard_False);
1829       }
1830       if (aChangeSet->ToSetLineWidth == 1)
1831       {
1832         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
1833       }
1834       else if (aChangeSet->ToSetLineWidth == -1)
1835       {
1836         aCtx->UnsetWidth (aPrs, Standard_False);
1837       }
1838
1839       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
1840       {
1841         aChangeSet = &aChangesIter.ChangeValue();
1842         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
1843              aSubShapeIter.More(); aSubShapeIter.Next())
1844         {
1845           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
1846           if (aChangeSet->ToSetColor == 1)
1847           {
1848             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
1849           }
1850           if (aChangeSet->ToSetLineWidth == 1)
1851           {
1852             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
1853           }
1854           if (aChangeSet->ToSetColor     == -1
1855            || aChangeSet->ToSetLineWidth == -1)
1856           {
1857             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
1858           }
1859         }
1860       }
1861       if (toDisplay)
1862       {
1863         aCtx->Display (aPrs, Standard_False);
1864       }
1865       else if (!aColoredPrs.IsNull())
1866       {
1867         aColoredPrs->Redisplay();
1868       }
1869     }
1870     else
1871     {
1872       Handle(NIS_InteractiveObject) aNisObj = Handle(NIS_InteractiveObject)::DownCast (aPrsIter.CurrentTrs());
1873       Handle(NIS_Triangulated)      aNisTri = Handle(NIS_Triangulated)::DownCast (aNisObj);
1874       if (!aNisObj.IsNull())
1875       {
1876         if (aChangeSet->ToSetTransparency != 0)
1877         {
1878           aNisObj->SetTransparency (aChangeSet->Transparency);
1879         }
1880       }
1881       if (!aNisTri.IsNull())
1882       {
1883         if (aChangeSet->ToSetColor != 0)
1884         {
1885           aNisTri->SetColor (aChangeSet->Color);
1886         }
1887         if (aChangeSet->ToSetLineWidth != 0)
1888         {
1889           aNisTri->SetLineWidth (aChangeSet->LineWidth);
1890         }
1891       }
1892     }
1893   }
1894
1895   // update the screen and redraw the view
1896   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
1897   a3DView()->SetImmediateUpdate (isAutoUpdate);
1898   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
1899    || aToUpdate == ViewerTest_RM_RedrawForce)
1900   {
1901     TheAISContext()->UpdateCurrentViewer();
1902   }
1903   return 0;
1904 }
1905
1906 //==============================================================================
1907 //function : VDonly2
1908 //author   : ege
1909 //purpose  : Display only a selected or named  object
1910 //           if there is no selected or named object s, nothing is done
1911 //==============================================================================
1912 static int VDonly2 (Draw_Interpretor& ,
1913                     Standard_Integer  theArgNb,
1914                     const char**      theArgVec)
1915 {
1916   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1917   if (aCtx.IsNull())
1918   {
1919     std::cerr << "Error: no active view!\n";
1920     return 1;
1921   }
1922
1923   if (aCtx->HasOpenedContext())
1924   {
1925     aCtx->CloseLocalContext();
1926   }
1927   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
1928
1929   Standard_Integer anArgIter = 1;
1930   for (; anArgIter < theArgNb; ++anArgIter)
1931   {
1932     if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate))
1933     {
1934       break;
1935     }
1936   }
1937
1938   NCollection_Map<Handle(Standard_Transient)> aDispSet;
1939   if (anArgIter >= theArgNb)
1940   {
1941     // display only selected objects
1942     if (aCtx->NbCurrents() < 1)
1943     {
1944       return 0;
1945     }
1946
1947     for (aCtx->InitCurrent(); aCtx->MoreCurrent(); aCtx->NextCurrent())
1948     {
1949       aDispSet.Add (aCtx->Current());
1950     }
1951   }
1952   else
1953   {
1954     // display only specified objects
1955     for (; anArgIter < theArgNb; ++anArgIter)
1956     {
1957       TCollection_AsciiString aName = theArgVec[anArgIter];
1958       if (GetMapOfAIS().IsBound2 (aName))
1959       {
1960         const Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
1961         if (anObj->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
1962         {
1963           const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
1964           aCtx->Display (aShape, Standard_False);
1965         }
1966         else if (anObj->IsKind (STANDARD_TYPE(NIS_InteractiveObject)))
1967         {
1968           Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anObj);
1969           TheNISContext()->Display (aShape);
1970         }
1971         aDispSet.Add (anObj);
1972       }
1973     }
1974   }
1975
1976   // weed out other objects
1977   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
1978   {
1979     if (aDispSet.Contains (anIter.Key1()))
1980     {
1981       continue;
1982     }
1983
1984     if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
1985     {
1986       const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
1987       aCtx->Erase (aShape, Standard_False);
1988     }
1989     else if (anIter.Key1()->IsKind (STANDARD_TYPE(NIS_InteractiveObject)))
1990     {
1991       const Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
1992       TheNISContext()->Erase (aShape);
1993     }
1994   }
1995
1996   // update the screen and redraw the view
1997   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
1998   a3DView()->SetImmediateUpdate (isAutoUpdate);
1999   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2000    || aToUpdate == ViewerTest_RM_RedrawForce)
2001   {
2002     TheAISContext()->UpdateCurrentViewer();
2003   }
2004
2005   return 0;
2006 }
2007
2008 //==============================================================================
2009 //function : VRemove
2010 //purpose  : Removes selected or named objects.
2011 //           If there is no selected or named objects,
2012 //           all objects in the viewer can be removed with argument -all.
2013 //           If -context is in arguments, the object is not deleted from the map of
2014 //           objects (deleted only from the current context).
2015 //==============================================================================
2016 int VRemove (Draw_Interpretor& theDI,
2017              Standard_Integer  theArgNb,
2018              const char**      theArgVec)
2019 {
2020   if (a3DView().IsNull())
2021   {
2022     std::cout << "Error: wrong syntax!\n";
2023     return 1;
2024   }
2025
2026   TheAISContext()->CloseAllContexts (Standard_False);
2027
2028   ViewerTest_RedrawMode aToUpdate     = ViewerTest_RM_Auto;
2029   Standard_Boolean      isContextOnly = Standard_False;
2030   Standard_Boolean      toRemoveAll   = Standard_False;
2031
2032   Standard_Integer anArgIter = 1;
2033   for (; anArgIter < theArgNb; ++anArgIter)
2034   {
2035     TCollection_AsciiString anArg = theArgVec[anArgIter];
2036     anArg.LowerCase();
2037     if (anArg == "-context")
2038     {
2039       isContextOnly = Standard_True;
2040     }
2041     else if (anArg == "-all")
2042     {
2043       toRemoveAll = Standard_True;
2044     }
2045     else if (!parseRedrawMode (anArg, aToUpdate))
2046     {
2047       break;
2048     }
2049   }
2050   if (toRemoveAll
2051    && anArgIter < theArgNb)
2052   {
2053     std::cout << "Error: wrong syntax!\n";
2054     return 1;
2055   }
2056
2057   NCollection_List<TCollection_AsciiString> anIONameList;
2058   if (toRemoveAll)
2059   {
2060     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2061          anIter.More(); anIter.Next())
2062     {
2063       anIONameList.Append (anIter.Key2());
2064     }
2065   }
2066   else if (anArgIter < theArgNb) // removed objects names are in argument list
2067   {
2068     for (; anArgIter < theArgNb; ++anArgIter)
2069     {
2070       TCollection_AsciiString aName = theArgVec[anArgIter];
2071       if (!GetMapOfAIS().IsBound2 (aName))
2072       {
2073         theDI << aName.ToCString() << " was not bound to some object.\n";
2074         continue;
2075       }
2076
2077       const Handle(Standard_Transient)& aTransientObj = GetMapOfAIS().Find2 (aName);
2078
2079       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aTransientObj);
2080       if (!anIO.IsNull())
2081       {
2082         if (anIO->GetContext() != TheAISContext())
2083         {
2084           theDI << aName.ToCString() << " was not displayed in current context.\n";
2085           theDI << "Please activate view with this object displayed and try again.\n";
2086           continue;
2087         }
2088
2089         anIONameList.Append (aName);
2090         continue;
2091       }
2092
2093       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (aTransientObj);
2094       if (!aNisIO.IsNull())
2095       {
2096         anIONameList.Append (aName);
2097       }
2098     }
2099   }
2100   else if (TheAISContext()->NbCurrents() > 0
2101         || TheNISContext()->GetSelected().Extent() > 0)
2102   {
2103     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2104          anIter.More(); anIter.Next())
2105     {
2106       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2107       if (!anIO.IsNull())
2108       {
2109         if (!TheAISContext()->IsCurrent (anIO))
2110         {
2111           continue;
2112         }
2113
2114         anIONameList.Append (anIter.Key2());
2115         continue;
2116       }
2117
2118       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2119       if (!aNisIO.IsNull())
2120       {
2121         if (!TheNISContext()->IsSelected (aNisIO))
2122         {
2123           continue;
2124         }
2125
2126         anIONameList.Append (anIter.Key2());
2127       }
2128     }
2129   }
2130
2131   // Unbind all removed objects from the map of displayed IO.
2132   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
2133        anIter.More(); anIter.Next())
2134   {
2135     const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2136
2137     if (!anIO.IsNull())
2138     {
2139       TheAISContext()->Remove (anIO, Standard_False);
2140       theDI << anIter.Value().ToCString() << " was removed\n";
2141     }
2142     else
2143     {
2144       const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2145       if (!aNisIO.IsNull())
2146       {
2147         TheNISContext()->Remove (aNisIO);
2148         theDI << anIter.Value().ToCString() << " was removed\n";
2149       }
2150     }
2151       
2152     if (!isContextOnly)
2153     {
2154       GetMapOfAIS().UnBind2 (anIter.Value());
2155     }
2156   }
2157
2158   // update the screen and redraw the view
2159   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2160   a3DView()->SetImmediateUpdate (isAutoUpdate);
2161   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2162    || aToUpdate == ViewerTest_RM_RedrawForce)
2163   {
2164     TheAISContext()->UpdateCurrentViewer();
2165   }
2166
2167   return 0;
2168 }
2169
2170 //==============================================================================
2171 //function : VErase
2172 //purpose  : Erase some selected or named objects
2173 //           if there is no selected or named objects, the whole viewer is erased
2174 //==============================================================================
2175 int VErase (Draw_Interpretor& theDI,
2176             Standard_Integer  theArgNb,
2177             const char**      theArgVec)
2178 {
2179   if (a3DView().IsNull())
2180   {
2181     std::cout << "Error: no active view!\n";
2182     return 1;
2183   }
2184   TheAISContext()->CloseAllContexts (Standard_False);
2185
2186   ViewerTest_RedrawMode  aToUpdate  = ViewerTest_RM_Auto;
2187   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
2188
2189   Standard_Integer anArgIter = 1;
2190   for (; anArgIter < theArgNb; ++anArgIter)
2191   {
2192     if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate))
2193     {
2194       break;
2195     }
2196   }
2197
2198   if (anArgIter < theArgNb)
2199   {
2200     if (toEraseAll)
2201     {
2202       std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
2203       return 1;
2204     }
2205
2206     // has a list of names
2207     for (; anArgIter < theArgNb; ++anArgIter)
2208     {
2209       TCollection_AsciiString aName = theArgVec[anArgIter];
2210       if (!GetMapOfAIS().IsBound2 (aName))
2211       {
2212         continue;
2213       }
2214
2215       const Handle(Standard_Transient)    anObj = GetMapOfAIS().Find2 (aName);
2216       const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (anObj);
2217       theDI << aName.ToCString() << " ";
2218       if (!anIO.IsNull())
2219       {
2220         TheAISContext()->Erase (anIO, Standard_False);
2221       }
2222       else
2223       {
2224         const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anObj);
2225         if (!aNisIO.IsNull())
2226         {
2227           TheNISContext()->Erase (aNisIO);
2228         }
2229       }
2230     }
2231   }
2232   else if (!toEraseAll
2233         && TheAISContext()->NbCurrents() > 0)
2234   {
2235     // remove all currently selected objects
2236     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2237          anIter.More(); anIter.Next())
2238     {
2239       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2240       if (!anIO.IsNull()
2241        && TheAISContext()->IsCurrent (anIO))
2242       {
2243         theDI << anIter.Key2().ToCString() << " ";
2244         TheAISContext()->Erase (anIO, Standard_False);
2245       }
2246     }
2247   }
2248   else
2249   {
2250     // erase entire viewer
2251     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2252          anIter.More(); anIter.Next())
2253     {
2254       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2255       if (!anIO.IsNull())
2256       {
2257         TheAISContext()->Erase (anIO, Standard_False);
2258       }
2259       else
2260       {
2261         const Handle(NIS_InteractiveObject) aNisIO = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2262         if (!aNisIO.IsNull())
2263         {
2264           TheNISContext()->Erase (aNisIO);
2265         }
2266       }
2267     }
2268   }
2269
2270   // update the screen and redraw the view
2271   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2272   a3DView()->SetImmediateUpdate (isAutoUpdate);
2273   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2274    || aToUpdate == ViewerTest_RM_RedrawForce)
2275   {
2276     TheAISContext()->UpdateCurrentViewer();
2277   }
2278
2279   return 0;
2280 }
2281
2282 //==============================================================================
2283 //function : VDisplayAll
2284 //author   : ege
2285 //purpose  : Display all the objects of the Map
2286 //==============================================================================
2287 static int VDisplayAll (Draw_Interpretor& ,
2288                         Standard_Integer  theArgNb,
2289                         const char**      theArgVec)
2290
2291 {
2292   if (a3DView().IsNull())
2293   {
2294     std::cout << "Error: no active view!\n";
2295     return 1;
2296   }
2297
2298   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
2299
2300   Standard_Integer anArgIter = 1;
2301   for (; anArgIter < theArgNb; ++anArgIter)
2302   {
2303     if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate))
2304     {
2305       break;
2306     }
2307   }
2308   if (anArgIter < theArgNb)
2309   {
2310     std::cout << theArgVec[0] << "Error: wrong syntax\n";
2311     return 1;
2312   }
2313
2314   if (TheAISContext()->HasOpenedContext())
2315   {
2316     TheAISContext()->CloseLocalContext();
2317   }
2318
2319   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2320        anIter.More(); anIter.Next())
2321   {
2322     if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
2323     {
2324       const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2325       TheAISContext()->Erase (aShape, Standard_False);
2326     }
2327     else if (anIter.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject)))
2328     {
2329       const Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2330       TheNISContext()->Erase (aShape);
2331     }
2332   }
2333
2334   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2335        anIter.More(); anIter.Next())
2336   {
2337     if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject)))
2338     {
2339       const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2340       TheAISContext()->Display (aShape, Standard_False);
2341     }
2342     else if (anIter.Key1()->IsKind (STANDARD_TYPE(NIS_InteractiveObject)))
2343     {
2344       Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anIter.Key1());
2345       TheNISContext()->Display (aShape);
2346     }
2347   }
2348
2349   // update the screen and redraw the view
2350   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2351   a3DView()->SetImmediateUpdate (isAutoUpdate);
2352   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2353    || aToUpdate == ViewerTest_RM_RedrawForce)
2354   {
2355     TheAISContext()->UpdateCurrentViewer();
2356   }
2357
2358   return 0;
2359 }
2360
2361 //==============================================================================
2362 //function : VTexture
2363 //purpose  :
2364 //==============================================================================
2365 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgv)
2366 {
2367   TCollection_AsciiString aCommandName (theArgv[0]);
2368
2369   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
2370   if (aCommandName == "vtexture")
2371   {
2372     if (theArgsNb < 2)
2373     {
2374       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
2375       std::cout << "Type help for more information.\n";
2376       return 1;
2377     }
2378
2379     // look for options of vtexture command
2380     TCollection_AsciiString aParseKey;
2381     for (Standard_Integer anArgIt = 2; anArgIt < theArgsNb; ++anArgIt)
2382     {
2383       TCollection_AsciiString anArg (theArgv [anArgIt]);
2384
2385       anArg.UpperCase();
2386       if (anArg.Value (1) == '-' && !anArg.IsRealValue())
2387       {
2388         aParseKey = anArg;
2389         aParseKey.Remove (1);
2390         aParseKey.UpperCase();
2391         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
2392         continue;
2393       }
2394
2395       if (aParseKey.IsEmpty())
2396       {
2397         continue;
2398       }
2399
2400       aMapOfArgs(aParseKey)->Append (anArg);
2401     }
2402   }
2403   else if (aCommandName == "vtexscale"
2404         || aCommandName == "vtexorigin"
2405         || aCommandName == "vtexrepeat")
2406   {
2407     // scan for parameters of vtexscale, vtexorigin, vtexrepeat commands
2408     // equal to -scale, -origin, -repeat options of vtexture command
2409     if (theArgsNb < 2 || theArgsNb > 4)
2410     {
2411       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
2412       std::cout << "Type help for more information.\n";
2413       return 1;
2414     }
2415
2416     Handle(TColStd_HSequenceOfAsciiString) anArgs = new TColStd_HSequenceOfAsciiString;
2417     if (theArgsNb == 2)
2418     {
2419       anArgs->Append ("OFF");
2420     }
2421     else if (theArgsNb == 4)
2422     {
2423       anArgs->Append (TCollection_AsciiString (theArgv[2]));
2424       anArgs->Append (TCollection_AsciiString (theArgv[3]));
2425     }
2426
2427     TCollection_AsciiString anArgKey;
2428     if (aCommandName == "vtexscale")
2429     {
2430       anArgKey = "SCALE";
2431     }
2432     else if (aCommandName == "vtexorigin")
2433     {
2434       anArgKey = "ORIGIN";
2435     }
2436     else
2437     {
2438       anArgKey = "REPEAT";
2439     }
2440
2441     aMapOfArgs.Bind (anArgKey, anArgs);
2442   }
2443   else if (aCommandName == "vtexdefault")
2444   {
2445     // scan for parameters of vtexdefault command
2446     // equal to -default option of vtexture command
2447     aMapOfArgs.Bind ("DEFAULT", new TColStd_HSequenceOfAsciiString);
2448   }
2449
2450   // Check arguments for validity
2451   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
2452   for (; aMapIt.More(); aMapIt.Next())
2453   {
2454     const TCollection_AsciiString& aKey = aMapIt.Key();
2455     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
2456
2457     // -scale, -origin, -repeat: one argument "off", or two real values
2458     if ((aKey.IsEqual ("SCALE") || aKey.IsEqual ("ORIGIN") || aKey.IsEqual ("REPEAT"))
2459       && ((anArgs->Length() == 1 && anArgs->Value(1) == "OFF")
2460        || (anArgs->Length() == 2 && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue())))
2461     {
2462       continue;
2463     }
2464
2465     // -modulate: single argument "on" / "off"
2466     if (aKey.IsEqual ("MODULATE") && anArgs->Length() == 1 && (anArgs->Value(1) == "OFF" || anArgs->Value(1) == "ON"))
2467     {
2468       continue;
2469     }
2470
2471     // -default: no arguments
2472     if (aKey.IsEqual ("DEFAULT") && anArgs->IsEmpty())
2473     {
2474       continue;
2475     }
2476
2477     TCollection_AsciiString aLowerKey;
2478     aLowerKey  = "-";
2479     aLowerKey += aKey;
2480     aLowerKey.LowerCase();
2481     std::cout << theArgv[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
2482     std::cout << "Type help for more information.\n";
2483     return 1;
2484   }
2485
2486   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
2487   if (anAISContext.IsNull())
2488   {
2489     std::cout << aCommandName << ": " << " please use 'vinit' command to initialize view.\n";
2490     return 1;
2491   }
2492
2493   Standard_Integer aPreviousMode = 0;
2494
2495   ViewerTest::CurrentView()->SetSurfaceDetail (V3d_TEX_ALL);
2496
2497   TCollection_AsciiString aShapeName (theArgv[1]);
2498   Handle(AIS_InteractiveObject) anIO;
2499
2500   const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
2501   if (aMapOfIO.IsBound2 (aShapeName))
2502   {
2503     anIO = Handle(AIS_InteractiveObject)::DownCast (aMapOfIO.Find2 (aShapeName));
2504   }
2505
2506   if (anIO.IsNull())
2507   {
2508     std::cout << aCommandName << ": shape " << aShapeName << " does not exists.\n";
2509     return 1;
2510   }
2511
2512   Handle(AIS_TexturedShape) aTexturedIO;
2513   if (anIO->IsKind (STANDARD_TYPE (AIS_TexturedShape)))
2514   {
2515     aTexturedIO = Handle(AIS_TexturedShape)::DownCast (anIO);
2516     aPreviousMode = aTexturedIO->DisplayMode();
2517   }
2518   else
2519   {
2520     anAISContext->Clear (anIO, Standard_False);
2521     aTexturedIO = new AIS_TexturedShape (DBRep::Get (theArgv[1]));
2522     GetMapOfAIS().UnBind1 (anIO);
2523     GetMapOfAIS().UnBind2 (aShapeName);
2524     GetMapOfAIS().Bind (aTexturedIO, aShapeName);
2525   }
2526
2527   // -------------------------------------------
2528   //  Turn texturing on/off - only for vtexture
2529   // -------------------------------------------
2530
2531   if (aCommandName == "vtexture")
2532   {
2533     TCollection_AsciiString aTextureArg (theArgsNb > 2 ? theArgv[2] : "");
2534
2535     if (aTextureArg.IsEmpty())
2536     {
2537       std::cout << aCommandName << ": " << " Texture mapping disabled.\n";
2538       std::cout << "To enable it, use 'vtexture NameOfShape NameOfTexture'\n" << "\n";
2539
2540       anAISContext->SetDisplayMode (aTexturedIO, AIS_Shaded, Standard_False);
2541       if (aPreviousMode == 3)
2542       {
2543         anAISContext->RecomputePrsOnly (aTexturedIO);
2544       }
2545
2546       anAISContext->Display (aTexturedIO, Standard_True);
2547       return 0;
2548     }
2549     else if (aTextureArg.Value(1) != '-') // "-option" on place of texture argument
2550     {
2551       if (aTextureArg == "?")
2552       {
2553         TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
2554
2555         theDi << "\n Files in current directory : \n" << "\n";
2556         theDi.Eval ("glob -nocomplain *");
2557
2558         TCollection_AsciiString aCmnd ("glob -nocomplain ");
2559         aCmnd += aTextureFolder;
2560         aCmnd += "/* ";
2561
2562         theDi << "Files in " << aTextureFolder.ToCString() << " : \n" << "\n";
2563         theDi.Eval (aCmnd.ToCString());
2564         return 0;
2565       }
2566       else
2567       {
2568         aTexturedIO->SetTextureFileName (aTextureArg);
2569       }
2570     }
2571   }
2572
2573   // ------------------------------------
2574   //  Process other options and commands
2575   // ------------------------------------
2576
2577   Handle(TColStd_HSequenceOfAsciiString) aValues;
2578   if (aMapOfArgs.Find ("DEFAULT", aValues))
2579   {
2580     aTexturedIO->SetTextureRepeat (Standard_False);
2581     aTexturedIO->SetTextureOrigin (Standard_False);
2582     aTexturedIO->SetTextureScale  (Standard_False);
2583     aTexturedIO->EnableTextureModulate();
2584   }
2585   else
2586   {
2587     if (aMapOfArgs.Find ("SCALE", aValues))
2588     {
2589       if (aValues->Value(1) != "OFF")
2590       {
2591         aTexturedIO->SetTextureScale (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2592       }
2593       else
2594       {
2595         aTexturedIO->SetTextureScale (Standard_False);
2596       }
2597     }
2598
2599     if (aMapOfArgs.Find ("ORIGIN", aValues))
2600     {
2601       if (aValues->Value(1) != "OFF")
2602       {
2603         aTexturedIO->SetTextureOrigin (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2604       }
2605       else
2606       {
2607         aTexturedIO->SetTextureOrigin (Standard_False);
2608       }
2609     }
2610
2611     if (aMapOfArgs.Find ("REPEAT", aValues))
2612     {
2613       if (aValues->Value(1) != "OFF")
2614       {
2615         aTexturedIO->SetTextureRepeat (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
2616       }
2617       else
2618       {
2619         aTexturedIO->SetTextureRepeat (Standard_False);
2620       }
2621     }
2622
2623     if (aMapOfArgs.Find ("MODULATE", aValues))
2624     {
2625       if (aValues->Value(1) == "ON")
2626       {
2627         aTexturedIO->EnableTextureModulate();
2628       }
2629       else
2630       {
2631         aTexturedIO->DisableTextureModulate();
2632       }
2633     }
2634   }
2635
2636   if (aTexturedIO->DisplayMode() == 3 || aPreviousMode == 3)
2637   {
2638     anAISContext->RecomputePrsOnly (aTexturedIO);
2639   }
2640   else
2641   {
2642     anAISContext->SetDisplayMode (aTexturedIO, 3, Standard_False);
2643     anAISContext->Display (aTexturedIO, Standard_True);
2644     anAISContext->Update (aTexturedIO,Standard_True);
2645   }
2646
2647   return 0;
2648 }
2649
2650 //==============================================================================
2651 //function : VDisplay2
2652 //author   : ege
2653 //purpose  : Display an object from its name
2654 //==============================================================================
2655 static int VDisplay2 (Draw_Interpretor& theDI,
2656                       Standard_Integer  theArgNb,
2657                       const char**      theArgVec)
2658 {
2659   if (theArgNb < 2)
2660   {
2661     std::cout << theArgVec[0] << "Error: wrong syntax!\n";
2662     return 1;
2663   }
2664   else if (a3DView().IsNull())
2665   {
2666     ViewerTest::ViewerInit();
2667     std::cout << "Command vinit should be called before!\n";
2668     // return 1;
2669   }
2670
2671   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2672   if (aCtx->HasOpenedContext())
2673   {
2674     aCtx->CloseLocalContext();
2675   }
2676
2677   ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
2678   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2679   {
2680     const TCollection_AsciiString aName = theArgVec[anArgIter];
2681     if (parseRedrawMode (aName, aToUpdate))
2682     {
2683       continue;
2684     }
2685     else if (!GetMapOfAIS().IsBound2 (aName))
2686     {
2687       // create the AIS_Shape from a name
2688       const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
2689       if (!aShape.IsNull())
2690       {
2691         GetMapOfAIS().Bind (aShape, aName);
2692         aCtx->Display (aShape, Standard_False);
2693       }
2694       continue;
2695     }
2696
2697     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
2698     if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject)))
2699     {
2700       Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
2701       if (aShape->Type() == AIS_KOI_Datum)
2702       {
2703         aCtx->Display (aShape, Standard_False);
2704       }
2705       else
2706       {
2707         theDI << "Display " << aName.ToCString() << "\n";
2708         // get the Shape from a name
2709         TopoDS_Shape aNewShape = GetShapeFromName (aName.ToCString());
2710
2711         // update the Shape in the AIS_Shape
2712         Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
2713         if (!aShapePrs.IsNull())
2714         {
2715           aShapePrs->Set (aNewShape);
2716         }
2717         aCtx->Redisplay (aShape, Standard_False);
2718         aCtx->Display   (aShape, Standard_False);
2719       }
2720       aShape.Nullify();
2721     }
2722     else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject)))
2723     {
2724       Handle(NIS_InteractiveObject) aShape = Handle(NIS_InteractiveObject)::DownCast (anObj);
2725       TheNISContext()->Display (aShape);
2726     }
2727   }
2728
2729   const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False);
2730   a3DView()->SetImmediateUpdate (isAutoUpdate);
2731   if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress)
2732    || aToUpdate == ViewerTest_RM_RedrawForce)
2733   {
2734     // update the screen and redraw the view
2735     aCtx->UpdateCurrentViewer();
2736   }
2737   return 0;
2738 }
2739
2740 //===============================================================================================
2741 //function : VUpdate
2742 //purpose  :
2743 //===============================================================================================
2744 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2745 {
2746   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2747   if (aContextAIS.IsNull())
2748   {
2749     std::cout << theArgVec[0] << "AIS context is not available.\n";
2750     return 1;
2751   }
2752
2753   if (theArgsNb < 2)
2754   {
2755     std::cout << theArgVec[0] << ": insufficient arguments. Type help for more information.\n";
2756     return 1;
2757   }
2758
2759   const ViewerTest_DoubleMapOfInteractiveAndName& anAISMap = GetMapOfAIS();
2760
2761   AIS_ListOfInteractive aListOfIO;
2762
2763   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
2764   {
2765     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
2766
2767     Handle(AIS_InteractiveObject) anAISObj;
2768     if (anAISMap.IsBound2 (aName))
2769     {
2770       anAISObj = Handle(AIS_InteractiveObject)::DownCast (anAISMap.Find2 (aName));
2771     }
2772
2773     if (anAISObj.IsNull())
2774     {
2775       std::cout << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".\n";
2776       return 1;
2777     }
2778
2779     aListOfIO.Append (anAISObj);
2780   }
2781
2782   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
2783   for (; anIOIt.More(); anIOIt.Next())
2784   {
2785     aContextAIS->Update (anIOIt.Value(), Standard_False);
2786   }
2787
2788   aContextAIS->UpdateCurrentViewer();
2789
2790   return 0;
2791 }
2792
2793 //==============================================================================
2794 //function : VPerf
2795 //purpose  : Test the annimation of an object along a
2796 //           predifined trajectory
2797 //Draw arg : vperf ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)
2798 //==============================================================================
2799
2800 static int VPerf(Draw_Interpretor& di, Standard_Integer , const char** argv) {
2801
2802   OSD_Timer myTimer;
2803   if (TheAISContext()->HasOpenedContext())
2804     TheAISContext()->CloseLocalContext();
2805
2806   Standard_Real Step=4*M_PI/180;
2807   Standard_Real Angle=0;
2808
2809   Handle(AIS_InteractiveObject) aIO;
2810   if (GetMapOfAIS().IsBound2(argv[1]))
2811     aIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
2812   if (aIO.IsNull())
2813     return 1;
2814
2815   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aIO);
2816
2817   myTimer.Start();
2818
2819   if (Draw::Atoi(argv[3])==1 ) {
2820     di<<" Primitives sensibles OFF"<<"\n";
2821     TheAISContext()->Deactivate(aIO);
2822   }
2823   else {
2824     di<<" Primitives sensibles ON"<<"\n";
2825   }
2826   // Movement par transformation
2827   if(Draw::Atoi(argv[2]) ==1) {
2828     di<<" Calcul par Transformation"<<"\n";
2829     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
2830
2831       Angle=Step*myAngle;
2832       gp_Trsf myTransfo;
2833       myTransfo.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ) ,Angle );
2834       TheAISContext()->SetLocation(aShape,myTransfo);
2835       TheAISContext() ->UpdateCurrentViewer();
2836
2837     }
2838   }
2839   else {
2840     di<<" Calcul par Locations"<<"\n";
2841     gp_Trsf myAngleTrsf;
2842     myAngleTrsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ), Step  );
2843     TopLoc_Location myDeltaAngle (myAngleTrsf);
2844     TopLoc_Location myTrueLoc;
2845
2846     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
2847
2848       Angle=Step*myAngle;
2849       myTrueLoc=myTrueLoc*myDeltaAngle;
2850       TheAISContext()->SetLocation(aShape,myTrueLoc );
2851       TheAISContext() ->UpdateCurrentViewer();
2852     }
2853   }
2854   if (Draw::Atoi(argv[3])==1 ){
2855     // On reactive la selection des primitives sensibles
2856     TheAISContext()->Activate(aIO,0);
2857   }
2858   a3DView() -> Redraw();
2859   myTimer.Stop();
2860   di<<" Temps ecoule "<<"\n";
2861   myTimer.Show();
2862   return 0;
2863 }
2864
2865
2866 //==================================================================================
2867 // Function : VAnimation
2868 //==================================================================================
2869 static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
2870   if (argc != 5) {
2871     di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile"<<"\n";
2872     return 1;
2873   }
2874
2875   Standard_Real thread = 4;
2876   Standard_Real angleA=0;
2877   Standard_Real angleB;
2878   Standard_Real X;
2879   gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
2880
2881   BRep_Builder B;
2882   TopoDS_Shape CrankArm;
2883   TopoDS_Shape CylinderHead;
2884   TopoDS_Shape Propeller;
2885   TopoDS_Shape EngineBlock;
2886
2887   //BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
2888   //BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
2889   //BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
2890   //BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
2891   BRepTools::Read(CrankArm,argv[1],B);
2892   BRepTools::Read(CylinderHead,argv[2],B);
2893   BRepTools::Read(Propeller,argv[3],B);
2894   BRepTools::Read(EngineBlock,argv[4],B);
2895
2896   if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure."<<"\n";}
2897
2898
2899   OSD_Timer myTimer;
2900   myTimer.Start();
2901
2902   Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
2903   Handle(AIS_Shape) myAisEngineBlock  = new AIS_Shape (EngineBlock);
2904   Handle(AIS_Shape) myAisCrankArm     = new AIS_Shape (CrankArm);
2905   Handle(AIS_Shape) myAisPropeller    = new AIS_Shape (Propeller);
2906
2907   GetMapOfAIS().Bind(myAisCylinderHead,"a");
2908   GetMapOfAIS().Bind(myAisEngineBlock,"b");
2909   GetMapOfAIS().Bind(myAisCrankArm,"c");
2910   GetMapOfAIS().Bind(myAisPropeller,"d");
2911
2912   TheAISContext()->SetColor(myAisCylinderHead, Quantity_NOC_INDIANRED);
2913   TheAISContext()->SetColor(myAisEngineBlock , Quantity_NOC_RED);
2914   TheAISContext()->SetColor(myAisPropeller   , Quantity_NOC_GREEN);
2915
2916   TheAISContext()->Display(myAisCylinderHead,Standard_False);
2917   TheAISContext()->Display(myAisEngineBlock,Standard_False );
2918   TheAISContext()->Display(myAisCrankArm,Standard_False    );
2919   TheAISContext()->Display(myAisPropeller,Standard_False);
2920
2921   TheAISContext()->Deactivate(myAisCylinderHead);
2922   TheAISContext()->Deactivate(myAisEngineBlock );
2923   TheAISContext()->Deactivate(myAisCrankArm    );
2924   TheAISContext()->Deactivate(myAisPropeller   );
2925
2926   // Boucle de mouvement
2927   for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
2928
2929     angleA = thread*myAngle*M_PI/180;
2930     X = Sin(angleA)*3/8;
2931     angleB = atan(X / Sqrt(-X * X + 1));
2932     Standard_Real decal(25*0.6);
2933
2934
2935     //Build a transformation on the display
2936     gp_Trsf aPropellerTrsf;
2937     aPropellerTrsf.SetRotation(Ax1,angleA);
2938     TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
2939
2940     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));
2941     gp_Trsf aCrankArmTrsf;
2942     aCrankArmTrsf.SetTransformation(   base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
2943     TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
2944
2945     TheAISContext()->UpdateCurrentViewer();
2946   }
2947
2948   TopoDS_Shape myNewCrankArm  =myAisCrankArm ->Shape().Located( myAisCrankArm ->Location() );
2949   TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Location() );
2950
2951   myAisCrankArm ->ResetLocation();
2952   myAisPropeller->ResetLocation();
2953
2954   myAisCrankArm  -> Set(myNewCrankArm );
2955   myAisPropeller -> Set(myNewPropeller);
2956
2957   TheAISContext()->Activate(myAisCylinderHead,0);
2958   TheAISContext()->Activate(myAisEngineBlock,0 );
2959   TheAISContext()->Activate(myAisCrankArm ,0   );
2960   TheAISContext()->Activate(myAisPropeller ,0  );
2961
2962   myTimer.Stop();
2963   myTimer.Show();
2964   myTimer.Start();
2965
2966   TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
2967   TheAISContext()->Redisplay(myAisPropeller,Standard_False);
2968
2969   TheAISContext()->UpdateCurrentViewer();
2970   a3DView()->Redraw();
2971
2972   myTimer.Stop();
2973   myTimer.Show();
2974
2975   return 0;
2976
2977 }
2978
2979 //==============================================================================
2980 //function : VShading
2981 //purpose  : Sharpen or roughten the quality of the shading
2982 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
2983 //==============================================================================
2984 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
2985 {
2986   Standard_Real    myDevCoef;
2987   Handle(AIS_InteractiveObject) TheAisIO;
2988
2989   // Verifications
2990   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
2991
2992   if (TheAISContext()->HasOpenedContext())
2993     TheAISContext()->CloseLocalContext();
2994
2995   if (argc < 3) {
2996     myDevCoef  = 0.0008;
2997   } else {
2998     myDevCoef  =Draw::Atof(argv[2]);
2999   }
3000
3001   TCollection_AsciiString name=argv[1];
3002   if (GetMapOfAIS().IsBound2(name ))
3003     TheAisIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
3004   if (TheAisIO.IsNull())
3005     TheAisIO=GetAISShapeFromName((const char *)name.ToCString());
3006
3007   if (HaveToSet)
3008     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
3009   else
3010     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
3011
3012   TheAISContext()->Redisplay(TheAisIO);
3013   return 0;
3014 }
3015 //==============================================================================
3016 //function : HaveMode
3017 //use      : VActivatedModes
3018 //==============================================================================
3019 #include <TColStd_ListIteratorOfListOfInteger.hxx>
3020
3021 Standard_Boolean  HaveMode(const Handle(AIS_InteractiveObject)& TheAisIO,const Standard_Integer mode  )
3022 {
3023   TColStd_ListOfInteger List;
3024   TheAISContext()->ActivatedModes (TheAisIO,List);
3025   TColStd_ListIteratorOfListOfInteger it;
3026   Standard_Boolean Found=Standard_False;
3027   for (it.Initialize(List); it.More()&&!Found; it.Next() ){
3028     if (it.Value()==mode ) Found=Standard_True;
3029   }
3030   return Found;
3031 }
3032
3033
3034
3035 //==============================================================================
3036 //function : VActivatedMode
3037 //author   : ege
3038 //purpose  : permet d'attribuer a chacune des shapes un mode d'activation
3039 //           (edges,vertex...)qui lui est propre et le mode de selection standard.
3040 //           La fonction s'applique aux shapes selectionnees(current ou selected dans le viewer)
3041 //             Dans le cas ou on veut psser la shape en argument, la fonction n'autorise
3042 //           qu'un nom et qu'un mode.
3043 //Draw arg : vsetam  [ShapeName] mode(0,1,2,3,4,5,6,7)
3044 //==============================================================================
3045 #include <AIS_ListIteratorOfListOfInteractive.hxx>
3046
3047 static int VActivatedMode (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3048
3049 {
3050   Standard_Boolean ThereIsName = Standard_False ;
3051
3052   if(!a3DView().IsNull()){
3053
3054     const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetam") == 0);
3055     // verification des arguments
3056     if (HaveToSet) {
3057       if (argc<2||argc>3) { di<<" Syntaxe error"<<"\n";return 1;}
3058       ThereIsName = (argc == 3);
3059     }
3060     else {
3061       // vunsetam
3062       if (argc>1) {di<<" Syntaxe error"<<"\n";return 1;}
3063       else {
3064         di<<" R.A.Z de tous les modes de selecion"<<"\n";
3065         di<<" Fermeture du Context local"<<"\n";
3066         if (TheAISContext()->HasOpenedContext())
3067           TheAISContext()->CloseLocalContext();
3068       }
3069     }
3070
3071     // IL n'y a aps de nom de shape passe en argument
3072     if (HaveToSet && !ThereIsName){
3073       Standard_Integer aMode=Draw::Atoi(argv [1]);
3074
3075       const char *cmode="???";
3076       switch (aMode) {
3077       case 0: cmode = "Shape"; break;
3078       case 1: cmode = "Vertex"; break;
3079       case 2: cmode = "Edge"; break;
3080       case 3: cmode = "Wire"; break;
3081       case 4: cmode = "Face"; break;
3082       case 5: cmode = "Shell"; break;
3083       case 6: cmode = "Solid"; break;
3084       case 7: cmode = "Compound"; break;
3085       }
3086
3087       if( !TheAISContext()->HasOpenedContext() ) {
3088         // il n'y a pas de Context local d'ouvert
3089         // on en ouvre un et on charge toutes les shapes displayees
3090         // on load tous les objets displayees et on Activate les objets de la liste
3091         AIS_ListOfInteractive ListOfIO;
3092         // on sauve dans une AISListOfInteractive tous les objets currents
3093         if (TheAISContext()->NbCurrents()>0 ){
3094           TheAISContext()->UnhilightCurrents(Standard_False);
3095
3096           for (TheAISContext()->InitCurrent(); TheAISContext()->MoreCurrent(); TheAISContext()->NextCurrent() ){
3097             ListOfIO.Append(TheAISContext()->Current() );
3098           }
3099         }
3100
3101         TheAISContext()->OpenLocalContext(Standard_False);
3102         ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3103           it (GetMapOfAIS());
3104         while(it.More()){
3105           Handle(AIS_InteractiveObject) aIO =
3106             Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3107           if (!aIO.IsNull())
3108             TheAISContext()->Load(aIO,0,Standard_False);
3109           it.Next();
3110         }
3111         // traitement des objets qui etaient currents dans le Contexte global
3112         if (!ListOfIO.IsEmpty() ) {
3113           // il y avait des objets currents
3114           AIS_ListIteratorOfListOfInteractive iter;
3115           for (iter.Initialize(ListOfIO); iter.More() ; iter.Next() ) {
3116             Handle(AIS_InteractiveObject) aIO=iter.Value();
3117             TheAISContext()->Activate(aIO,aMode);
3118             di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString()  <<"\n";
3119           }
3120         }
3121         else {
3122           // On applique le mode a tous les objets displayes
3123           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3124             it2 (GetMapOfAIS());
3125           while(it2.More()){
3126             Handle(AIS_InteractiveObject) aIO =
3127               Handle(AIS_InteractiveObject)::DownCast(it2.Key1());
3128             if (!aIO.IsNull()) {
3129               di<<" Mode: "<<cmode<<" ON pour "<<it2.Key2().ToCString() <<"\n";
3130               TheAISContext()->Activate(aIO,aMode);
3131             }
3132             it2.Next();
3133           }
3134         }
3135
3136       }
3137
3138       else {
3139         // un Context local est deja ouvert
3140         // Traitement des objets du Context local
3141         if (TheAISContext()->NbSelected()>0 ){
3142           TheAISContext()->UnhilightSelected(Standard_False);
3143           // il y a des objets selected,on les parcourt
3144           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
3145             Handle(AIS_InteractiveObject) aIO=TheAISContext()->Interactive();
3146
3147
3148             if (HaveMode(aIO,aMode) ) {
3149               di<<" Mode: "<<cmode<<" OFF pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3150               TheAISContext()->Deactivate(aIO,aMode);
3151             }
3152             else{
3153               di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3154               TheAISContext()->Activate(aIO,aMode);
3155             }
3156
3157           }
3158         }
3159         else{
3160           // il n'y a pas d'objets selected
3161           // tous les objets diplayes sont traites
3162           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
3163             it (GetMapOfAIS());
3164           while(it.More()){
3165             Handle(AIS_InteractiveObject) aIO =
3166               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3167             if (!aIO.IsNull()) {
3168               if (HaveMode(aIO,aMode) ) {
3169                 di<<" Mode: "<<cmode<<" OFF pour "
3170                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3171                 TheAISContext()->Deactivate(aIO,aMode);
3172               }
3173               else{
3174                 di<<" Mode: "<<cmode<<" ON pour"
3175                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
3176                 TheAISContext()->Activate(aIO,aMode);
3177               }
3178             }
3179             it.Next();
3180           }
3181         }
3182       }
3183     }
3184     else if (HaveToSet && ThereIsName){
3185       Standard_Integer aMode=Draw::Atoi(argv [2]);
3186       Handle(AIS_InteractiveObject) aIO =
3187         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
3188
3189       if (!aIO.IsNull()) {
3190         const char *cmode="???";
3191
3192         switch (aMode) {
3193         case 0: cmode = "Shape"; break;
3194         case 1: cmode = "Vertex"; break;
3195         case 2: cmode = "Edge"; break;
3196         case 3: cmode = "Wire"; break;
3197         case 4: cmode = "Face"; break;
3198         case 5: cmode = "Shell"; break;
3199         case 6: cmode = "Solid"; break;
3200         case 7: cmode = "Compound"; break;
3201         }
3202
3203         if( !TheAISContext()->HasOpenedContext() ) {
3204           TheAISContext()->OpenLocalContext(Standard_False);
3205           // On charge tous les objets de la map
3206           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it (GetMapOfAIS());
3207           while(it.More()){
3208             Handle(AIS_InteractiveObject) aShape=
3209               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
3210             if (!aShape.IsNull())
3211               TheAISContext()->Load(aShape,0,Standard_False);
3212             it.Next();
3213           }
3214           TheAISContext()->Activate(aIO,aMode);
3215           di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
3216         }
3217
3218         else {
3219           // un Context local est deja ouvert
3220           if (HaveMode(aIO,aMode) ) {
3221             di<<" Mode: "<<cmode<<" OFF pour "<<argv[1]<<"\n";
3222             TheAISContext()->Deactivate(aIO,aMode);
3223           }
3224           else{
3225             di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
3226             TheAISContext()->Activate(aIO,aMode);
3227           }
3228         }
3229       }
3230     }
3231   }
3232   return 0;
3233 }
3234
3235 //! Auxiliary method to print Interactive Object information
3236 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
3237                      const Handle(Standard_Transient)&                     theObject,
3238                      Draw_Interpretor&                                     theDI)
3239 {
3240   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theObject);
3241   if (anObj.IsNull())
3242   {
3243     theDI << theObject->DynamicType()->Name() << " is not AIS presentation\n";
3244     return;
3245   }
3246
3247   theDI << (TheAISContext()->IsDisplayed  (anObj) ? "Displayed"  : "Hidden   ")
3248         << (TheAISContext()->IsSelected   (anObj) ? " Selected" : "         ")
3249         << (theDetected.Contains (anObj)          ? " Detected" : "         ")
3250         << " Type: ";
3251   if (anObj->Type() == AIS_KOI_Datum)
3252   {
3253     // AIS_Datum
3254     if      (anObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
3255     else if (anObj->Signature() == 2) { theDI << " AIS_Axis"; }
3256     else if (anObj->Signature() == 6) { theDI << " AIS_Circle"; }
3257     else if (anObj->Signature() == 5) { theDI << " AIS_Line"; }
3258     else if (anObj->Signature() == 7) { theDI << " AIS_Plane"; }
3259     else if (anObj->Signature() == 1) { theDI << " AIS_Point"; }
3260     else if (anObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
3261   }
3262   // AIS_Shape
3263   else if (anObj->Type()      == AIS_KOI_Shape
3264         && anObj->Signature() == 0)
3265   {
3266     theDI << " AIS_Shape";
3267   }
3268   else if (anObj->Type() == AIS_KOI_Relation)
3269   {
3270     // AIS_Dimention and AIS_Relation
3271     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (anObj);
3272     switch (aRelation->KindOfDimension())
3273     {
3274       case AIS_KOD_PLANEANGLE:     theDI << " AIS_AngleDimension"; break;
3275       case AIS_KOD_LENGTH:         theDI << " AIS_Chamf2/3dDimension/AIS_LengthDimension"; break;
3276       case AIS_KOD_DIAMETER:       theDI << " AIS_DiameterDimension"; break;
3277       case AIS_KOD_ELLIPSERADIUS:  theDI << " AIS_EllipseRadiusDimension"; break;
3278       //case AIS_KOD_FILLETRADIUS:   theDI << " AIS_FilletRadiusDimension "; break;
3279       case AIS_KOD_OFFSET:         theDI << " AIS_OffsetDimension"; break;
3280       case AIS_KOD_RADIUS:         theDI << " AIS_RadiusDimension"; break;
3281       default:                     theDI << " UNKNOWN dimension"; break;
3282     }
3283   }
3284   else
3285   {
3286     theDI << " UserPrs";
3287   }
3288   theDI << " (" << theObject->DynamicType()->Name() << ")";
3289 }
3290
3291 //! Print information about locally selected sub-shapes
3292 static void localCtxInfo (Draw_Interpretor& theDI)
3293 {
3294   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
3295   if (!aCtx->HasOpenedContext())
3296   {
3297     return;
3298   }
3299
3300   TCollection_AsciiString aPrevName;
3301   Handle(AIS_LocalContext) aCtxLoc = aCtx->LocalContext();
3302   for (aCtxLoc->InitSelected(); aCtxLoc->MoreSelected(); aCtxLoc->NextSelected())
3303   {
3304     const TopoDS_Shape      aSubShape = aCtxLoc->SelectedShape();
3305     const Handle(AIS_Shape) aShapeIO  = Handle(AIS_Shape)::DownCast (aCtxLoc->SelectedInteractive());
3306     if (aSubShape.IsNull()
3307       || aShapeIO.IsNull()
3308       || !GetMapOfAIS().IsBound1 (aShapeIO))
3309     {
3310       continue;
3311     }
3312
3313     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
3314     TopTools_MapOfShape aFilter;
3315     Standard_Integer    aNumber = 0;
3316     const TopoDS_Shape  aShape  = aShapeIO->Shape();
3317     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
3318          anIter.More(); anIter.Next())
3319     {
3320       if (!aFilter.Add (anIter.Current()))
3321       {
3322         continue; // filter duplicates
3323       }
3324
3325       ++aNumber;
3326       if (!anIter.Current().IsSame (aSubShape))
3327       {
3328         continue;
3329       }
3330
3331       Standard_CString aShapeName = NULL;
3332       switch (aSubShape.ShapeType())
3333       {
3334         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
3335         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
3336         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
3337         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
3338         case TopAbs_FACE:      aShapeName = "     Face"; break;
3339         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
3340         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
3341         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
3342         default:
3343         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
3344       }
3345
3346       if (aParentName != aPrevName)
3347       {
3348         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
3349         aPrevName = aParentName;
3350       }
3351       theDI << "  " << aShapeName << " #" << aNumber << "\n";
3352       break;
3353     }
3354   }
3355 }
3356
3357 //==============================================================================
3358 //function : VState
3359 //purpose  :
3360 //Draw arg : vstate [nameA] ... [nameN]
3361 //==============================================================================
3362 static Standard_Integer VState (Draw_Interpretor& theDI,
3363                                 Standard_Integer  theArgNb,
3364                                 Standard_CString* theArgVec)
3365 {
3366   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
3367   if (aCtx.IsNull())
3368   {
3369     std::cerr << "Error: No opened viewer!\n";
3370     return 1;
3371   }
3372
3373   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
3374   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
3375   {
3376     aDetected.Add (aCtx->DetectedCurrentObject());
3377   }
3378
3379   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
3380   if (theArgNb >= 2
3381    && !toShowAll)
3382   {
3383     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3384     {
3385       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
3386       if (!GetMapOfAIS().IsBound2 (anObjName))
3387       {
3388         theDI << anObjName << " doesn't exist!\n";
3389         continue;
3390       }
3391
3392       const Handle(Standard_Transient) anObjTrans = GetMapOfAIS().Find2 (anObjName);
3393       TCollection_AsciiString aName = anObjName;
3394       aName.LeftJustify (20, ' ');
3395       theDI << "  " << aName << " ";
3396       objInfo (aDetected, anObjTrans, theDI);
3397       theDI << "\n";
3398     }
3399     return 0;
3400   }
3401
3402   if (aCtx->NbCurrents() > 0
3403    && !toShowAll)
3404   {
3405     for (aCtx->InitCurrent(); aCtx->MoreCurrent(); aCtx->NextCurrent())
3406     {
3407       Handle(AIS_InteractiveObject) anObj = aCtx->Current();
3408       TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
3409       aName.LeftJustify (20, ' ');
3410       theDI << aName << " ";
3411       objInfo (aDetected, anObj, theDI);
3412       theDI << "\n";
3413     }
3414     return 0;
3415   }
3416
3417   theDI << "Neutral-point state:\n";
3418   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
3419        anObjIter.More(); anObjIter.Next())
3420   {
3421     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anObjIter.Key1());
3422     if (anObj.IsNull())
3423     {
3424       continue;
3425     }
3426
3427     TCollection_AsciiString aName = anObjIter.Key2();
3428     aName.LeftJustify (20, ' ');
3429     theDI << "  " << aName << " ";
3430     objInfo (aDetected, anObj, theDI);
3431     theDI << "\n";
3432   }
3433   localCtxInfo (theDI);
3434   return 0;
3435 }
3436
3437 //=======================================================================
3438 //function : PickObjects
3439 //purpose  :
3440 //=======================================================================
3441 Standard_Boolean  ViewerTest::PickObjects(Handle(TColStd_HArray1OfTransient)& arr,
3442                                           const AIS_KindOfInteractive TheType,
3443                                           const Standard_Integer TheSignature,
3444                                           const Standard_Integer MaxPick)
3445 {
3446   Handle(AIS_InteractiveObject) IO;
3447   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
3448
3449   // step 1: prepare the data
3450   if(curindex !=0){
3451     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
3452     TheAISContext()->AddFilter(F1);
3453   }
3454
3455   // step 2 : wait for the selection...
3456 //  Standard_Boolean IsGood (Standard_False);
3457 //  Standard_Integer NbPick(0);
3458   Standard_Boolean NbPickGood (0),NbToReach(arr->Length());
3459   Standard_Integer NbPickFail(0);
3460   Standard_Integer argccc = 5;
3461   const char *bufff[] = { "A", "B", "C","D", "E" };
3462   const char **argvvv = (const char **) bufff;
3463
3464
3465   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
3466     while(ViewerMainLoop(argccc,argvvv)){}
3467     Standard_Integer NbStored = TheAISContext()->NbSelected();
3468     if((unsigned int ) NbStored != NbPickGood)
3469       NbPickGood= NbStored;
3470     else
3471       NbPickFail++;
3472     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<endl;
3473   }
3474
3475   // step3 get result.
3476
3477   if((unsigned int ) NbPickFail >= NbToReach) return Standard_False;
3478
3479   Standard_Integer i(0);
3480   for(TheAISContext()->InitSelected();
3481       TheAISContext()->MoreSelected();
3482       TheAISContext()->NextSelected()){
3483     i++;
3484     Handle(AIS_InteractiveObject) IO2 = TheAISContext()->SelectedInteractive();
3485     arr->SetValue(i,IO2);
3486   }
3487
3488
3489   if(curindex>0)
3490     TheAISContext()->CloseLocalContext(curindex);
3491
3492   return Standard_True;
3493 }
3494
3495
3496 //=======================================================================
3497 //function : PickObject
3498 //purpose  :
3499 //=======================================================================
3500 Handle(AIS_InteractiveObject) ViewerTest::PickObject(const AIS_KindOfInteractive TheType,
3501                                                      const Standard_Integer TheSignature,
3502                                                      const Standard_Integer MaxPick)
3503 {
3504   Handle(AIS_InteractiveObject) IO;
3505   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
3506
3507   // step 1: prepare the data
3508
3509   if(curindex !=0){
3510     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
3511     TheAISContext()->AddFilter(F1);
3512   }
3513
3514   // step 2 : wait for the selection...
3515   Standard_Boolean IsGood (Standard_False);
3516   Standard_Integer NbPick(0);
3517   Standard_Integer argccc = 5;
3518   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
3519   const char **argvvv = (const char **) bufff;
3520
3521
3522   while(!IsGood && NbPick<= MaxPick){
3523     while(ViewerMainLoop(argccc,argvvv)){}
3524     IsGood = (TheAISContext()->NbSelected()>0) ;
3525     NbPick++;
3526     cout<<"Nb Pick :"<<NbPick<<endl;
3527   }
3528
3529
3530   // step3 get result.
3531   if(IsGood){
3532     TheAISContext()->InitSelected();
3533     IO = TheAISContext()->SelectedInteractive();
3534   }
3535
3536   if(curindex!=0)
3537     TheAISContext()->CloseLocalContext(curindex);
3538   return IO;
3539 }
3540
3541 //=======================================================================
3542 //function : PickShape
3543 //purpose  : First Activate the rightmode + Put Filters to be able to
3544 //           pick objets that are of type <TheType>...
3545 //=======================================================================
3546
3547 TopoDS_Shape ViewerTest::PickShape(const TopAbs_ShapeEnum TheType,
3548                                    const Standard_Integer MaxPick)
3549 {
3550
3551   // step 1: prepare the data
3552
3553   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
3554   TopoDS_Shape result;
3555
3556   if(TheType==TopAbs_SHAPE){
3557     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
3558     TheAISContext()->AddFilter(F1);
3559   }
3560   else{
3561     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
3562     TheAISContext()->AddFilter(TF);
3563     TheAISContext()->ActivateStandardMode(TheType);
3564
3565   }
3566
3567
3568   // step 2 : wait for the selection...
3569   Standard_Boolean NoShape (Standard_True);
3570   Standard_Integer NbPick(0);
3571   Standard_Integer argccc = 5;
3572   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
3573   const char **argvvv = (const char **) bufff;
3574
3575
3576   while(NoShape && NbPick<= MaxPick){
3577     while(ViewerMainLoop(argccc,argvvv)){}
3578     NoShape = (TheAISContext()->NbSelected()==0) ;
3579     NbPick++;
3580     cout<<"Nb Pick :"<<NbPick<<endl;
3581   }
3582
3583   // step3 get result.
3584
3585   if(!NoShape){
3586
3587     TheAISContext()->InitSelected();
3588     if(TheAISContext()->HasSelectedShape())
3589       result = TheAISContext()->SelectedShape();
3590     else{
3591       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
3592       result = (*((Handle(AIS_Shape)*) &IO))->Shape();
3593     }
3594   }
3595
3596   if(curindex>0)
3597     TheAISContext()->CloseLocalContext(curindex);
3598
3599   return result;
3600 }
3601
3602
3603 //=======================================================================
3604 //function : PickShapes
3605 //purpose  :
3606 //=======================================================================
3607 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum TheType,
3608                                          Handle(TopTools_HArray1OfShape)& thearr,
3609                                          const Standard_Integer MaxPick)
3610 {
3611
3612   Standard_Integer Taille = thearr->Length();
3613   if(Taille>1)
3614     cout<<" WARNING : Pick with Shift+ MB1 for Selection of more than 1 object"<<"\n";
3615
3616   // step 1: prepare the data
3617   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
3618   if(TheType==TopAbs_SHAPE){
3619     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
3620     TheAISContext()->AddFilter(F1);
3621   }
3622   else{
3623     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
3624     TheAISContext()->AddFilter(TF);
3625     TheAISContext()->ActivateStandardMode(TheType);
3626
3627   }
3628
3629   // step 2 : wait for the selection...
3630
3631   Standard_Boolean NbPickGood (0),NbToReach(thearr->Length());
3632   Standard_Integer NbPickFail(0);
3633   Standard_Integer argccc = 5;
3634   const char *bufff[] = { "A", "B", "C","D", "E" };
3635   const char **argvvv = (const char **) bufff;
3636
3637
3638   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
3639     while(ViewerMainLoop(argccc,argvvv)){}
3640     Standard_Integer NbStored = TheAISContext()->NbSelected();
3641     if((unsigned int ) NbStored != NbPickGood)
3642       NbPickGood= NbStored;
3643     else
3644       NbPickFail++;
3645     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<"\n";
3646   }
3647
3648   // step3 get result.
3649
3650   if((unsigned int ) NbPickFail >= NbToReach) return Standard_False;
3651
3652   Standard_Integer i(0);
3653   for(TheAISContext()->InitSelected();TheAISContext()->MoreSelected();TheAISContext()->NextSelected()){
3654     i++;
3655     if(TheAISContext()->HasSelectedShape())
3656       thearr->SetValue(i,TheAISContext()->SelectedShape());
3657     else{
3658       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
3659       thearr->SetValue(i,(*((Handle(AIS_Shape)*) &IO))->Shape());
3660     }
3661   }
3662
3663   TheAISContext()->CloseLocalContext(curindex);
3664   return Standard_True;
3665 }
3666
3667
3668 //=======================================================================
3669 //function : VPickShape
3670 //purpose  :
3671 //=======================================================================
3672 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3673 {
3674   TopoDS_Shape PickSh;
3675   TopAbs_ShapeEnum theType = TopAbs_COMPOUND;
3676
3677   if(argc==1)
3678     theType = TopAbs_SHAPE;
3679   else{
3680     if(!strcasecmp(argv[1],"V" )) theType = TopAbs_VERTEX;
3681     else if (!strcasecmp(argv[1],"E" )) theType = TopAbs_EDGE;
3682     else if (!strcasecmp(argv[1],"W" )) theType = TopAbs_WIRE;
3683     else if (!strcasecmp(argv[1],"F" )) theType = TopAbs_FACE;
3684     else if(!strcasecmp(argv[1],"SHAPE" )) theType = TopAbs_SHAPE;
3685     else if (!strcasecmp(argv[1],"SHELL" )) theType = TopAbs_SHELL;
3686     else if (!strcasecmp(argv[1],"SOLID" )) theType = TopAbs_SOLID;
3687   }
3688
3689   static Standard_Integer nbOfSub[8]={0,0,0,0,0,0,0,0};
3690   static TCollection_AsciiString nameType[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
3691
3692   TCollection_AsciiString name;
3693
3694
3695   Standard_Integer NbToPick = argc>2 ? argc-2 : 1;
3696   if(NbToPick==1){
3697     PickSh = ViewerTest::PickShape(theType);
3698
3699     if(PickSh.IsNull())