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