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