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