1fc28ba9d279c88b98cb7cd15abb562c1db67589
[occt.git] / src / ViewerTest / ViewerTest.cxx
1 // Created on: 1997-07-23
2 // Created by: Henri JEANNIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by  Eric Gouthiere [sep-oct 98] -> add commands for display...
18 // Modified by  Robert Coublanc [nov 16-17-18 1998]
19 //             -split ViewerTest.cxx into 3 files : ViewerTest.cxx,
20 //                                                  ViewerTest_ObjectCommands.cxx
21 //                                                  ViewerTest_RelationCommands.cxx
22 //             -add Functions and commands for interactive selection of shapes and objects
23 //              in AIS Viewers. (PickShape(s), PickObject(s),
24
25 #include <Standard_Stream.hxx>
26
27 #include <ViewerTest.hxx>
28 #include <ViewerTest_CmdParser.hxx>
29
30 #include <TopLoc_Location.hxx>
31 #include <TopTools_HArray1OfShape.hxx>
32 #include <TColStd_HArray1OfTransient.hxx>
33 #include <TColStd_SequenceOfAsciiString.hxx>
34 #include <TColStd_HSequenceOfAsciiString.hxx>
35 #include <TColStd_MapOfTransient.hxx>
36 #include <OSD_Timer.hxx>
37 #include <Geom_Axis2Placement.hxx>
38 #include <Geom_Axis1Placement.hxx>
39 #include <gp_Trsf.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <BRepAdaptor_Curve.hxx>
42 #include <StdSelect_ShapeTypeFilter.hxx>
43 #include <AIS.hxx>
44 #include <AIS_ColoredShape.hxx>
45 #include <AIS_InteractiveObject.hxx>
46 #include <AIS_Trihedron.hxx>
47 #include <AIS_Axis.hxx>
48 #include <AIS_Relation.hxx>
49 #include <AIS_TypeFilter.hxx>
50 #include <AIS_SignatureFilter.hxx>
51 #include <AIS_LocalContext.hxx>
52 #include <AIS_ListOfInteractive.hxx>
53 #include <AIS_ListIteratorOfListOfInteractive.hxx>
54 #include <Aspect_InteriorStyle.hxx>
55 #include <Aspect_Window.hxx>
56 #include <Graphic3d_AspectFillArea3d.hxx>
57 #include <Graphic3d_AspectLine3d.hxx>
58 #include <Graphic3d_CStructure.hxx>
59 #include <Graphic3d_TextureRoot.hxx>
60 #include <Image_AlienPixMap.hxx>
61 #include <Prs3d_Drawer.hxx>
62 #include <Prs3d_ShadingAspect.hxx>
63 #include <Prs3d_IsoAspect.hxx>
64 #include <Prs3d_PointAspect.hxx>
65 #include <Select3D_SensitiveWire.hxx>
66 #include <SelectMgr_EntityOwner.hxx>
67 #include <StdSelect_BRepOwner.hxx>
68 #include <StdSelect_ViewerSelector3d.hxx>
69 #include <TopTools_MapOfShape.hxx>
70 #include <ViewerTest_AutoUpdater.hxx>
71
72 #include <stdio.h>
73
74 #include <Draw_Interpretor.hxx>
75 #include <TCollection_AsciiString.hxx>
76 #include <Draw_PluginMacro.hxx>
77
78 // avoid warnings on 'extern "C"' functions returning C++ classes
79 #ifdef _MSC_VER
80 #define _CRT_SECURE_NO_DEPRECATE
81 #pragma warning(4:4190)
82 #pragma warning (disable:4996)
83 #endif
84
85 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
86
87 #include <Quantity_Color.hxx>
88 #include <Quantity_NameOfColor.hxx>
89
90 #include <Graphic3d_NameOfMaterial.hxx>
91
92 #define DEFAULT_COLOR              Quantity_NOC_GOLDENROD
93 #define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
94 #define DEFAULT_MATERIAL           Graphic3d_NOM_BRASS
95
96 //=======================================================================
97 //function : GetColorFromName
98 //purpose  : get the Quantity_NameOfColor from a string
99 //=======================================================================
100
101 Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
102 {
103   Quantity_NameOfColor aColor = DEFAULT_COLOR;
104   Quantity_Color::ColorFromName (theName, aColor);
105   return aColor;
106 }
107
108 //=======================================================================
109 //function : ParseColor
110 //purpose  :
111 //=======================================================================
112
113 Standard_Integer ViewerTest::ParseColor (Standard_Integer  theArgNb,
114                                          const char**      theArgVec,
115                                          Quantity_Color&   theColor)
116 {
117   Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
118   if (theArgNb >= 1
119    && Quantity_Color::ColorFromName (theArgVec[0], aColor))
120   {
121     theColor = aColor;
122     return 1;
123   }
124   else if (theArgNb >= 3)
125   {
126     const TCollection_AsciiString anRgbStr[3] =
127     {
128       theArgVec[0],
129       theArgVec[1],
130       theArgVec[2]
131     };
132     if (!anRgbStr[0].IsRealValue()
133      || !anRgbStr[1].IsRealValue()
134      || !anRgbStr[2].IsRealValue())
135     {
136       return 0;
137     }
138
139     Graphic3d_Vec4d anRgb;
140     anRgb.x() = anRgbStr[0].RealValue();
141     anRgb.y() = anRgbStr[1].RealValue();
142     anRgb.z() = anRgbStr[2].RealValue();
143     if (anRgb.x() < 0.0 || anRgb.x() > 1.0
144      || anRgb.y() < 0.0 || anRgb.y() > 1.0
145      || anRgb.z() < 0.0 || anRgb.z() > 1.0)
146     {
147       std::cout << "Error: RGB color values should be within range 0..1!\n";
148       return 0;
149     }
150
151     theColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
152     return 3;
153   }
154
155   return 0;
156 }
157
158 //=======================================================================
159 //function : ParseOnOff
160 //purpose  :
161 //=======================================================================
162 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
163                                          Standard_Boolean& theIsOn)
164 {
165   TCollection_AsciiString aFlag(theArg);
166   aFlag.LowerCase();
167   if (aFlag == "on"
168    || aFlag == "1")
169   {
170     theIsOn = Standard_True;
171     return Standard_True;
172   }
173   else if (aFlag == "off"
174         || aFlag == "0")
175   {
176     theIsOn = Standard_False;
177     return Standard_True;
178   }
179   return Standard_False;
180 }
181
182 //=======================================================================
183 //function : GetTypeNames
184 //purpose  :
185 //=======================================================================
186 static const char** GetTypeNames()
187 {
188   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
189                           "Shape","ConnectedShape","MultiConn.Shape",
190                           "ConnectedInter.","MultiConn.",
191                           "Constraint","Dimension"};
192   static const char** ThePointer = names;
193   return ThePointer;
194 }
195
196 //=======================================================================
197 //function : GetTypeAndSignfromString
198 //purpose  :
199 //=======================================================================
200 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
201 {
202   const char ** thefullnames = GetTypeNames();
203   Standard_Integer index(-1);
204
205   for(Standard_Integer i=0;i<=13 && index==-1;i++)
206     if(!strcasecmp(name,thefullnames[i]))
207       index = i;
208
209   if(index ==-1){
210     TheType = AIS_KOI_None;
211     TheSign = -1;
212     return;
213   }
214
215   if(index<=6){
216     TheType = AIS_KOI_Datum;
217     TheSign = index+1;
218   }
219   else if (index <=9){
220     TheType = AIS_KOI_Shape;
221     TheSign = index-7;
222   }
223   else if(index<=11){
224     TheType = AIS_KOI_Object;
225     TheSign = index-10;
226   }
227   else{
228     TheType = AIS_KOI_Relation;
229     TheSign = index-12;
230   }
231
232 }
233
234
235
236 #include <string.h>
237 #include <Draw_Interpretor.hxx>
238 #include <Draw.hxx>
239 #include <Draw_Appli.hxx>
240 #include <DBRep.hxx>
241
242
243 #include <TCollection_AsciiString.hxx>
244 #include <V3d_Viewer.hxx>
245 #include <V3d_View.hxx>
246 #include <V3d.hxx>
247
248 #include <AIS_InteractiveContext.hxx>
249 #include <AIS_Shape.hxx>
250 #include <AIS_TexturedShape.hxx>
251 #include <AIS_DisplayMode.hxx>
252 #include <TColStd_MapOfInteger.hxx>
253 #include <AIS_MapOfInteractive.hxx>
254 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
255 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
256 #include <ViewerTest_EventManager.hxx>
257
258 #include <TopoDS_Solid.hxx>
259 #include <BRepTools.hxx>
260 #include <BRep_Builder.hxx>
261 #include <TopAbs_ShapeEnum.hxx>
262
263 #include <TopoDS.hxx>
264 #include <BRep_Tool.hxx>
265
266
267 #include <Draw_Window.hxx>
268 #include <AIS_ListIteratorOfListOfInteractive.hxx>
269 #include <AIS_ListOfInteractive.hxx>
270 #include <AIS_DisplayMode.hxx>
271 #include <TopTools_ListOfShape.hxx>
272 #include <BRepOffsetAPI_MakeThickSolid.hxx>
273 #include <BRepOffset.hxx>
274
275 //==============================================================================
276 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
277 //==============================================================================
278 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
279   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
280   return TheMap;
281 }
282
283 //=======================================================================
284 //function : Display
285 //purpose  :
286 //=======================================================================
287 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
288                                       const Handle(AIS_InteractiveObject)& theObject,
289                                       const Standard_Boolean               theToUpdate,
290                                       const Standard_Boolean               theReplaceIfExists)
291 {
292   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
293   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
294   if (aCtx.IsNull())
295   {
296     std::cout << "Error: AIS context is not available.\n";
297     return Standard_False;
298   }
299
300   if (aMap.IsBound2 (theName))
301   {
302     if (!theReplaceIfExists)
303     {
304       std::cout << "Error: other interactive object has been already registered with name: " << theName << ".\n"
305                 << "Please use another name.\n";
306       return Standard_False;
307     }
308
309     Handle(AIS_InteractiveObject) anOldObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theName));
310     if (!anOldObj.IsNull())
311     {
312       aCtx->Remove (anOldObj, Standard_True);
313     }
314     aMap.UnBind2 (theName);
315   }
316
317   if (theObject.IsNull())
318   {
319     // object with specified name has been already unbound
320     return Standard_True;
321   }
322
323   // unbind AIS object if it was bound with another name
324   aMap.UnBind1 (theObject);
325
326   // can be registered without rebinding
327   aMap.Bind (theObject, theName);
328   aCtx->Display (theObject, theToUpdate);
329   return Standard_True;
330 }
331
332 //! Alias for ViewerTest::Display(), compatibility with old code.
333 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
334                                                     const Handle(AIS_InteractiveObject)& theObject,
335                                                     Standard_Boolean theReplaceIfExists = Standard_True)
336 {
337   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
338 }
339
340 static TColStd_MapOfInteger theactivatedmodes(8);
341 static TColStd_ListOfTransient theEventMgrs;
342
343 static void VwrTst_InitEventMgr(const Handle(V3d_View)& aView,
344                                 const Handle(AIS_InteractiveContext)& Ctx)
345 {
346   theEventMgrs.Clear();
347   theEventMgrs.Prepend(new ViewerTest_EventManager(aView, Ctx));
348 }
349
350 static Handle(V3d_View)&  a3DView()
351 {
352   static Handle(V3d_View) Viou;
353   return Viou;
354 }
355
356
357 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
358   static Handle(AIS_InteractiveContext) aContext;
359   return aContext;
360 }
361
362 const Handle(V3d_View)& ViewerTest::CurrentView()
363 {
364   return a3DView();
365 }
366 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
367 {
368   a3DView() = V;
369 }
370
371 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
372 {
373   return TheAISContext();
374 }
375
376 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
377 {
378   TheAISContext() = aCtx;
379   ViewerTest::ResetEventManager();
380 }
381
382 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
383 {
384   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
385 }
386
387 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
388 {
389   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
390 }
391
392
393 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
394   theEventMgrs.Prepend(EM);
395 }
396
397 void ViewerTest::UnsetEventManager()
398 {
399   theEventMgrs.RemoveFirst();
400 }
401
402
403 void ViewerTest::ResetEventManager()
404 {
405   const Handle(V3d_View) aView = ViewerTest::CurrentView();
406   VwrTst_InitEventMgr(aView, ViewerTest::GetAISContext());
407 }
408
409 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
410 {
411   Handle(ViewerTest_EventManager) EM;
412   if(theEventMgrs.IsEmpty()) return EM;
413   Handle(Standard_Transient) Tr =  theEventMgrs.First();
414   EM = Handle(ViewerTest_EventManager)::DownCast (Tr);
415   return EM;
416 }
417
418 //=======================================================================
419 //function : Get Context and active view
420 //purpose  :
421 //=======================================================================
422 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
423                                        Handle(V3d_View)&               theView)
424 {
425   theCtx  = ViewerTest::GetAISContext();
426   theView = ViewerTest::CurrentView();
427   if (theCtx.IsNull()
428    || theView.IsNull())
429   {
430     std::cout << "Error: cannot find an active view!\n";
431     return Standard_False;
432   }
433   return Standard_True;
434 }
435
436 //==============================================================================
437 //function : GetShapeFromName
438 //purpose  : Compute an Shape from a draw variable or a file name
439 //==============================================================================
440
441 static TopoDS_Shape GetShapeFromName(const char* name)
442 {
443   TopoDS_Shape S = DBRep::Get(name);
444
445   if ( S.IsNull() ) {
446         BRep_Builder aBuilder;
447         BRepTools::Read( S, name, aBuilder);
448   }
449
450   return S;
451 }
452
453 //==============================================================================
454 //function : GetAISShapeFromName
455 //purpose  : Compute an AIS_Shape from a draw variable or a file name
456 //==============================================================================
457 Handle(AIS_Shape) GetAISShapeFromName(const char* name)
458 {
459   Handle(AIS_Shape) retsh;
460
461   if(GetMapOfAIS().IsBound2(name)){
462     const Handle(AIS_InteractiveObject) IO =
463       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
464     if (!IO.IsNull()) {
465       if(IO->Type()==AIS_KOI_Shape) {
466         if(IO->Signature()==0){
467           retsh = Handle(AIS_Shape)::DownCast (IO);
468         }
469         else
470           cout << "an Object which is not an AIS_Shape "
471             "already has this name!!!"<<endl;
472       }
473     }
474     return retsh;
475   }
476
477
478   TopoDS_Shape S = GetShapeFromName(name);
479   if ( !S.IsNull() ) {
480     retsh = new AIS_Shape(S);
481   }
482   return retsh;
483 }
484
485
486 //==============================================================================
487 //function : Clear
488 //purpose  : Remove all the object from the viewer
489 //==============================================================================
490 void ViewerTest::Clear()
491 {
492   if ( !a3DView().IsNull() ) {
493     if (TheAISContext()->HasOpenedContext())
494       TheAISContext()->CloseLocalContext();
495     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it(GetMapOfAIS());
496     while ( it.More() ) {
497       cout << "Remove " << it.Key2() << endl;
498       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (it.Key1());
499       TheAISContext()->Remove(anObj,Standard_False);
500       it.Next();
501     }
502     TheAISContext()->RebuildSelectionStructs();
503     TheAISContext()->UpdateCurrentViewer();
504     GetMapOfAIS().Clear();
505   }
506 }
507
508 //==============================================================================
509 //function : StandardModesActivation
510 //purpose  : Activate a selection mode, vertex, edge, wire ..., in a local
511 //           Context
512 //==============================================================================
513 void ViewerTest::StandardModeActivation(const Standard_Integer mode )
514 {
515   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
516   if(mode==0) {
517     if (TheAISContext()->HasOpenedContext())
518       aContext->CloseLocalContext();
519   } else {
520
521     if(!aContext->HasOpenedContext()) {
522       // To unhilight the preselected object
523       aContext->UnhilightSelected(Standard_False);
524       // Open a local Context in order to be able to select subshape from
525       // the selected shape if any or for all if there is no selection
526       if (!aContext->FirstSelectedObject().IsNull()){
527         aContext->OpenLocalContext(Standard_False);
528
529         for(aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected()){
530           aContext->Load(       aContext->SelectedInteractive(),-1,Standard_True);
531         }
532       }
533       else
534         aContext->OpenLocalContext();
535     }
536
537     const char *cmode="???";
538
539     switch (mode) {
540     case 0: cmode = "Shape"; break;
541     case 1: cmode = "Vertex"; break;
542     case 2: cmode = "Edge"; break;
543     case 3: cmode = "Wire"; break;
544     case 4: cmode = "Face"; break;
545     case 5: cmode = "Shell"; break;
546     case 6: cmode = "Solid"; break;
547     case 7: cmode = "Compsolid"; break;
548     case 8: cmode = "Compound"; break;
549     }
550
551     if(theactivatedmodes.Contains(mode))
552       { // Desactivate
553         aContext->DeactivateStandardMode(AIS_Shape::SelectionType(mode));
554         theactivatedmodes.Remove(mode);
555         cout<<"Mode "<< cmode <<" OFF"<<endl;
556       }
557     else
558       { // Activate
559         aContext->ActivateStandardMode(AIS_Shape::SelectionType(mode));
560         theactivatedmodes.Add(mode);
561         cout<<"Mode "<< cmode << " ON" << endl;
562       }
563   }
564 }
565
566 //==============================================================================
567 //function : CopyIsoAspect
568 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
569 //==============================================================================
570 static Handle(Prs3d_IsoAspect) CopyIsoAspect
571       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
572        const Standard_Integer theNbIsos)
573 {
574   Quantity_Color    aColor;
575   Aspect_TypeOfLine aType;
576   Standard_Real     aWidth;
577
578   theIsoAspect->Aspect()->Values(aColor, aType, aWidth);
579
580   Handle(Prs3d_IsoAspect) aResult =
581     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
582
583   return aResult;
584 }
585
586 //==============================================================================
587 //function : visos
588 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
589 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
590 //==============================================================================
591 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
592 {
593   if (TheAISContext().IsNull()) {
594     di << argv[0] << " Call 'vinit' before!\n";
595     return 1;
596   }
597
598   if (argc <= 1) {
599     di << "Current number of isos : " <<
600       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
601       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
602     di << "IsoOnPlane mode is " <<
603       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
604     di << "IsoOnTriangulation mode is " <<
605       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
606     return 0;
607   }
608
609   Standard_Integer aLastInd = argc - 1;
610   Standard_Boolean isChanged = Standard_False;
611   Standard_Integer aNbUIsos = 0;
612   Standard_Integer aNbVIsos = 0;
613
614   if (aLastInd >= 3) {
615     Standard_Boolean isIsoOnPlane = Standard_False;
616
617     if (strcmp(argv[aLastInd], "1") == 0) {
618       isIsoOnPlane = Standard_True;
619       isChanged    = Standard_True;
620     } else if (strcmp(argv[aLastInd], "0") == 0) {
621       isIsoOnPlane = Standard_False;
622       isChanged    = Standard_True;
623     }
624
625     if (isChanged) {
626       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
627       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
628       aLastInd -= 3;
629
630       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
631       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
632
633       TheAISContext()->IsoOnPlane(isIsoOnPlane);
634
635       if (aLastInd == 0) {
636         // If there are no shapes provided set the default numbers.
637         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
638         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
639       }
640     }
641   }
642
643   Standard_Integer i;
644
645   for (i = 1; i <= aLastInd; i++) {
646     TCollection_AsciiString name(argv[i]);
647     Standard_Boolean IsBound = GetMapOfAIS().IsBound2(name);
648
649     if (IsBound) {
650       const Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(name);
651       if (anObj->IsKind(STANDARD_TYPE(AIS_InteractiveObject))) {
652         const Handle(AIS_InteractiveObject) aShape =
653         Handle(AIS_InteractiveObject)::DownCast (anObj);
654         Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
655         Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
656         Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
657
658         if (isChanged) {
659           CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
660           CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
661           TheAISContext()->SetLocalAttributes
662                   (aShape, CurDrawer, Standard_False);
663           TheAISContext()->Redisplay(aShape);
664         } else {
665           di << "Number of isos for " << argv[i] << " : "
666              << aUIso->Number() << " " << aVIso->Number() << "\n";
667         }
668       } else {
669         di << argv[i] << ": Not an AIS interactive object!\n";
670       }
671     } else {
672       di << argv[i] << ": Use 'vdisplay' before\n";
673     }
674   }
675
676   if (isChanged) {
677     TheAISContext()->UpdateCurrentViewer();
678   }
679
680   return 0;
681 }
682
683 static Standard_Integer VDispSensi (Draw_Interpretor& ,
684                                     Standard_Integer  theArgNb,
685                                     Standard_CString* )
686 {
687   if (theArgNb > 1)
688   {
689     std::cout << "Error: wrong syntax!\n";
690     return 1;
691   }
692
693   Handle(AIS_InteractiveContext) aCtx;
694   Handle(V3d_View)               aView;
695   if (!getCtxAndView (aCtx, aView))
696   {
697     return 1;
698   }
699
700   aCtx->DisplayActiveSensitive (aView);
701   return 0;
702
703 }
704
705 static Standard_Integer VClearSensi (Draw_Interpretor& ,
706                                      Standard_Integer  theArgNb,
707                                      Standard_CString* )
708 {
709   if (theArgNb > 1)
710   {
711     std::cout << "Error: wrong syntax!\n";
712     return 1;
713   }
714
715   Handle(AIS_InteractiveContext) aCtx;
716   Handle(V3d_View)               aView;
717   if (!getCtxAndView (aCtx, aView))
718   {
719     return 1;
720   }
721   aCtx->ClearActiveSensitive (aView);
722   return 0;
723 }
724
725 //==============================================================================
726 //function : VDir
727 //purpose  : To list the displayed object with their attributes
728 //==============================================================================
729 static int VDir (Draw_Interpretor& theDI,
730                  Standard_Integer ,
731                  const char** )
732 {
733   if (!a3DView().IsNull())
734   {
735     return 0;
736   }
737
738   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
739        anIter.More(); anIter.Next())
740   {
741     theDI << "\t" << anIter.Key2().ToCString() << "\n";
742   }
743   return 0;
744 }
745
746 //==============================================================================
747 //function : VSelPrecision
748 //purpose  : To set the selection tolerance value
749 //Draw arg : Selection tolerance value (real value determining the width and
750 //           height of selecting frustum bases). Without arguments the function
751 //           just prints current tolerance.
752 //==============================================================================
753 static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
754 {
755   if( argc > 2 )
756   {
757     di << "Wrong parameters! Must be: " << argv[0] << " [-unset] [tolerance]\n";
758     return 1;
759   }
760
761   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
762   if( aContext.IsNull() )
763     return 1;
764
765   if( argc == 1 )
766   {
767     Standard_Real aPixelTolerance = aContext->PixelTolerance();
768     di << "Pixel tolerance : " << aPixelTolerance << "\n";
769   }
770   else if (argc == 2)
771   {
772     TCollection_AsciiString anArg = TCollection_AsciiString (argv[1]);
773     anArg.LowerCase();
774     if (anArg == "-unset")
775     {
776       aContext->SetPixelTolerance (-1);
777     }
778     else
779     {
780       aContext->SetPixelTolerance (anArg.IntegerValue());
781     }
782   }
783
784   return 0;
785 }
786
787 //! Auxiliary enumeration
788 enum ViewerTest_StereoPair
789 {
790   ViewerTest_SP_Single,
791   ViewerTest_SP_SideBySide,
792   ViewerTest_SP_OverUnder
793 };
794
795 //==============================================================================
796 //function : VDump
797 //purpose  : To dump the active view snapshot to image file
798 //==============================================================================
799 static Standard_Integer VDump (Draw_Interpretor& theDI,
800                                Standard_Integer  theArgNb,
801                                Standard_CString* theArgVec)
802 {
803   if (theArgNb < 2)
804   {
805     std::cout << "Error: wrong number of arguments! Image file name should be specified at least.\n";
806     return 1;
807   }
808
809   Standard_Integer      anArgIter   = 1;
810   Standard_CString      aFilePath   = theArgVec[anArgIter++];
811   Graphic3d_BufferType  aBufferType = Graphic3d_BT_RGB;
812   V3d_StereoDumpOptions aStereoOpts = V3d_SDO_MONO;
813   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
814   Standard_Integer      aWidth      = 0;
815   Standard_Integer      aHeight     = 0;
816   for (; anArgIter < theArgNb; ++anArgIter)
817   {
818     TCollection_AsciiString anArg (theArgVec[anArgIter]);
819     anArg.LowerCase();
820     if (anArg == "-buffer")
821     {
822       if (++anArgIter >= theArgNb)
823       {
824         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
825         return 1;
826       }
827
828       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
829       aBufArg.LowerCase();
830       if (aBufArg == "rgba")
831       {
832         aBufferType = Graphic3d_BT_RGBA;
833       }
834       else if (aBufArg == "rgb")
835       {
836         aBufferType = Graphic3d_BT_RGB;
837       }
838       else if (aBufArg == "depth")
839       {
840         aBufferType = Graphic3d_BT_Depth;
841       }
842       else
843       {
844         std::cout << "Error: unknown buffer '" << aBufArg << "'\n";
845         return 1;
846       }
847     }
848     else if (anArg == "-stereo")
849     {
850       if (++anArgIter >= theArgNb)
851       {
852         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
853         return 1;
854       }
855
856       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
857       aStereoArg.LowerCase();
858       if (aStereoArg == "l"
859        || aStereoArg == "left")
860       {
861         aStereoOpts = V3d_SDO_LEFT_EYE;
862       }
863       else if (aStereoArg == "r"
864             || aStereoArg == "right")
865       {
866         aStereoOpts = V3d_SDO_RIGHT_EYE;
867       }
868       else if (aStereoArg == "mono")
869       {
870         aStereoOpts = V3d_SDO_MONO;
871       }
872       else if (aStereoArg == "blended"
873             || aStereoArg == "blend"
874             || aStereoArg == "stereo")
875       {
876         aStereoOpts = V3d_SDO_BLENDED;
877       }
878       else if (aStereoArg == "sbs"
879             || aStereoArg == "sidebyside")
880       {
881         aStereoPair = ViewerTest_SP_SideBySide;
882       }
883       else if (aStereoArg == "ou"
884             || aStereoArg == "overunder")
885       {
886         aStereoPair = ViewerTest_SP_OverUnder;
887       }
888       else
889       {
890         std::cout << "Error: unknown stereo format '" << aStereoArg << "'\n";
891         return 1;
892       }
893     }
894     else if (anArg == "-rgba"
895           || anArg ==  "rgba")
896     {
897       aBufferType = Graphic3d_BT_RGBA;
898     }
899     else if (anArg == "-rgb"
900           || anArg ==  "rgb")
901     {
902       aBufferType = Graphic3d_BT_RGB;
903     }
904     else if (anArg == "-depth"
905           || anArg ==  "depth")
906     {
907       aBufferType = Graphic3d_BT_Depth;
908     }
909
910     else if (anArg == "-width"
911           || anArg ==  "width"
912           || anArg ==  "sizex")
913     {
914       if (aWidth != 0)
915       {
916         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
917         return 1;
918       }
919       else if (++anArgIter >= theArgNb)
920       {
921         std::cout << "Error: integer value is expected right after 'width'\n";
922         return 1;
923       }
924       aWidth = Draw::Atoi (theArgVec[anArgIter]);
925     }
926     else if (anArg == "-height"
927           || anArg ==  "height"
928           || anArg ==  "-sizey")
929     {
930       if (aHeight != 0)
931       {
932         std::cout << "Error: wrong syntax at " << theArgVec[anArgIter] << "\n";
933         return 1;
934       }
935       else if (++anArgIter >= theArgNb)
936       {
937         std::cout << "Error: integer value is expected right after 'height'\n";
938         return 1;
939       }
940       aHeight = Draw::Atoi (theArgVec[anArgIter]);
941     }
942     else
943     {
944       std::cout << "Error: unknown argument '" << theArgVec[anArgIter] << "'\n";
945       return 1;
946     }
947   }
948   if ((aWidth <= 0 && aHeight >  0)
949    || (aWidth >  0 && aHeight <= 0))
950   {
951     std::cout << "Error: dimensions " << aWidth << "x" << aHeight << " are incorrect\n";
952     return 1;
953   }
954
955   Handle(V3d_View) aView = ViewerTest::CurrentView();
956   if (aView.IsNull())
957   {
958     std::cout << "Error: cannot find an active view!\n";
959     return 1;
960   }
961
962   if (aWidth <= 0 || aHeight <= 0)
963   {
964     aView->Window()->Size (aWidth, aHeight);
965   }
966
967   Image_AlienPixMap aPixMap;
968
969   bool isBigEndian = Image_PixMap::IsBigEndianHost();
970   Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
971   switch (aBufferType)
972   {
973     case Graphic3d_BT_RGB:   aFormat = isBigEndian ? Image_PixMap::ImgRGB  : Image_PixMap::ImgBGR;  break;
974     case Graphic3d_BT_RGBA:  aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
975     case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
976   }
977
978   switch (aStereoPair)
979   {
980     case ViewerTest_SP_Single:
981     {
982       if (!aView->ToPixMap (aPixMap, aWidth, aHeight, aBufferType, Standard_True, aStereoOpts))
983       {
984         theDI << "Fail: view dump failed!\n";
985         return 0;
986       }
987       else if (aPixMap.SizeX() != Standard_Size(aWidth)
988             || aPixMap.SizeY() != Standard_Size(aHeight))
989       {
990         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
991               << " are lesser than requested " << aWidth << "x" << aHeight << "\n";
992       }
993       break;
994     }
995     case ViewerTest_SP_SideBySide:
996     {
997       if (!aPixMap.InitZero (aFormat, aWidth * 2, aHeight))
998       {
999         theDI << "Fail: not enough memory for image allocation!\n";
1000         return 0;
1001       }
1002
1003       Image_PixMap aPixMapL, aPixMapR;
1004       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1005                             aWidth, aHeight, aPixMap.SizeRowBytes());
1006       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aWidth,
1007                             aWidth, aHeight, aPixMap.SizeRowBytes());
1008       if (!aView->ToPixMap (aPixMapL, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_LEFT_EYE)
1009        || !aView->ToPixMap (aPixMapR, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_RIGHT_EYE)
1010        )
1011       {
1012         theDI << "Fail: view dump failed!\n";
1013         return 0;
1014       }
1015       break;
1016     }
1017     case ViewerTest_SP_OverUnder:
1018     {
1019       if (!aPixMap.InitZero (aFormat, aWidth, aHeight * 2))
1020       {
1021         theDI << "Fail: not enough memory for image allocation!\n";
1022         return 0;
1023       }
1024
1025       Image_PixMap aPixMapL, aPixMapR;
1026       aPixMapL.InitWrapper (aFormat, aPixMap.ChangeData(),
1027                             aWidth, aHeight, aPixMap.SizeRowBytes());
1028       aPixMapR.InitWrapper (aFormat, aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aHeight,
1029                             aWidth, aHeight, aPixMap.SizeRowBytes());
1030       if (!aView->ToPixMap (aPixMapL, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_LEFT_EYE)
1031        || !aView->ToPixMap (aPixMapR, aWidth, aHeight, aBufferType, Standard_True, V3d_SDO_RIGHT_EYE))
1032       {
1033         theDI << "Fail: view dump failed!\n";
1034         return 0;
1035       }
1036       break;
1037     }
1038   }
1039
1040   if (!aPixMap.Save (aFilePath))
1041   {
1042     theDI << "Fail: image can not be saved!\n";
1043   }
1044   return 0;
1045 }
1046
1047 //==============================================================================
1048 //function : Displays,Erase...
1049 //purpose  :
1050 //Draw arg :
1051 //==============================================================================
1052 static int VwrTst_DispErase(const Handle(AIS_InteractiveObject)& IO,
1053                             const Standard_Integer Mode,
1054                             const Standard_Integer TypeOfOperation,
1055                             const Standard_Boolean Upd)
1056 {
1057   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1058
1059   switch(TypeOfOperation){
1060   case 1:
1061     Ctx->Display(IO,Mode,Upd);
1062     break;
1063   case 2:{
1064     Ctx->Erase(IO,Upd);
1065     break;
1066   }
1067   case 3:{
1068     if(IO.IsNull())
1069       Ctx->SetDisplayMode((AIS_DisplayMode)Mode,Upd);
1070     else
1071       Ctx->SetDisplayMode(IO,Mode,Upd);
1072     break;
1073   }
1074   case 4:{
1075     if(IO.IsNull())
1076       Ctx->SetDisplayMode(0,Upd);
1077     else
1078       Ctx->UnsetDisplayMode(IO,Upd);
1079     break;
1080   }
1081   }
1082   return 0;
1083 }
1084
1085 //=======================================================================
1086 //function :
1087 //purpose  :
1088 //=======================================================================
1089 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1090 {
1091
1092   TCollection_AsciiString name;
1093   if(argc>3)
1094     return 1;
1095   // display others presentations
1096   Standard_Integer TypeOfOperation = (strcasecmp(argv[0],"vdispmode")==0)? 1:
1097     (strcasecmp(argv[0],"verasemode")==0) ? 2 :
1098       (strcasecmp(argv[0],"vsetdispmode")==0) ? 3 :
1099         (strcasecmp(argv[0],"vunsetdispmode")==0) ? 4 : -1;
1100
1101   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1102
1103   //unset displaymode.. comportement particulier...
1104   if(TypeOfOperation==4){
1105     if(argc==1){
1106       if(Ctx->NbSelected()==0){
1107         Handle(AIS_InteractiveObject) IO;
1108         VwrTst_DispErase(IO,-1,4,Standard_False);
1109       }
1110       else{
1111         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1112           VwrTst_DispErase(Ctx->SelectedInteractive(),-1,4,Standard_False);}
1113       Ctx->UpdateCurrentViewer();
1114     }
1115     else{
1116       Handle(AIS_InteractiveObject) IO;
1117       name = argv[1];
1118       if(GetMapOfAIS().IsBound2(name)){
1119         IO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
1120         if (!IO.IsNull())
1121           VwrTst_DispErase(IO,-1,4,Standard_True);
1122       }
1123     }
1124   }
1125   else if(argc==2){
1126     Standard_Integer Dmode = Draw::Atoi(argv[1]);
1127     if(Ctx->NbSelected()==0 && TypeOfOperation==3){
1128       Handle(AIS_InteractiveObject) IO;
1129       VwrTst_DispErase(IO,Dmode,TypeOfOperation,Standard_True);
1130     }
1131     if(!Ctx->HasOpenedContext()){
1132       // set/unset display mode sur le Contexte...
1133       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected()){
1134         VwrTst_DispErase(Ctx->SelectedInteractive(),Dmode,TypeOfOperation,Standard_False);
1135       }
1136       Ctx->UpdateCurrentViewer();
1137     }
1138     else{
1139       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1140         Ctx->Display(Ctx->SelectedInteractive(),Dmode);
1141     }
1142   }
1143   else{
1144     Handle(AIS_InteractiveObject) IO;
1145     name = argv[1];
1146     if(GetMapOfAIS().IsBound2(name))
1147       IO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
1148     if (!IO.IsNull())
1149       VwrTst_DispErase(IO,Draw::Atoi(argv[2]),TypeOfOperation,Standard_True);
1150   }
1151   return 0;
1152 }
1153
1154
1155 //=======================================================================
1156 //function :
1157 //purpose  :
1158 //=======================================================================
1159 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1160 {
1161   if(argc==1) return 1;
1162   Standard_Integer On = Draw::Atoi(argv[1]);
1163   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1164
1165   if(argc==2)
1166   {
1167     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1168     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1169     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1170     {
1171       if(On==1)
1172       {
1173         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1174       }
1175       else
1176       {
1177         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1178       }
1179     }
1180
1181     Ctx->UpdateCurrentViewer();
1182   }
1183   else {
1184     Handle(AIS_InteractiveObject) IO;
1185     TCollection_AsciiString name = argv[2];
1186     if(GetMapOfAIS().IsBound2(name)){
1187       IO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
1188       if (!IO.IsNull()) {
1189         if(On==1)
1190           Ctx->SubIntensityOn(IO);
1191         else
1192           Ctx->SubIntensityOff(IO);
1193       }
1194     }
1195     else return 1;
1196   }
1197   return 0;
1198 }
1199
1200 //! Auxiliary class to iterate presentations from different collections.
1201 class ViewTest_PrsIter
1202 {
1203 public:
1204
1205   //! Create and initialize iterator object.
1206   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1207   : mySource (IterSource_All)
1208   {
1209     NCollection_Sequence<TCollection_AsciiString> aNames;
1210     if (!theName.IsEmpty())
1211     aNames.Append (theName);
1212     Init (aNames);
1213   }
1214
1215   //! Create and initialize iterator object.
1216   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1217   : mySource (IterSource_All)
1218   {
1219     Init (theNames);
1220   }
1221
1222   //! Initialize the iterator.
1223   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1224   {
1225     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1226     mySeq = theNames;
1227     mySelIter.Nullify();
1228     myCurrent.Nullify();
1229     myCurrentTrs.Nullify();
1230     if (!mySeq.IsEmpty())
1231     {
1232       mySource = IterSource_List;
1233       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1234     }
1235     else if (aCtx->NbSelected() > 0)
1236     {
1237       mySource  = IterSource_Selected;
1238       mySelIter = aCtx;
1239       mySelIter->InitSelected();
1240     }
1241     else
1242     {
1243       mySource = IterSource_All;
1244       myMapIter.Initialize (GetMapOfAIS());
1245     }
1246     initCurrent();
1247   }
1248
1249   const TCollection_AsciiString& CurrentName() const
1250   {
1251     return myCurrentName;
1252   }
1253
1254   const Handle(AIS_InteractiveObject)& Current() const
1255   {
1256     return myCurrent;
1257   }
1258
1259   const Handle(Standard_Transient)& CurrentTrs() const
1260   {
1261     return myCurrentTrs;
1262   }
1263
1264   //! @return true if iterator points to valid object within collection
1265   Standard_Boolean More() const
1266   {
1267     switch (mySource)
1268     {
1269       case IterSource_All:      return myMapIter.More();
1270       case IterSource_List:     return mySeqIter.More();
1271       case IterSource_Selected: return mySelIter->MoreSelected();
1272     }
1273     return Standard_False;
1274   }
1275
1276   //! Go to the next item.
1277   void Next()
1278   {
1279     myCurrentName.Clear();
1280     myCurrentTrs.Nullify();
1281     myCurrent.Nullify();
1282     switch (mySource)
1283     {
1284       case IterSource_All:
1285       {
1286         myMapIter.Next();
1287         break;
1288       }
1289       case IterSource_List:
1290       {
1291         mySeqIter.Next();
1292         break;
1293       }
1294       case IterSource_Selected:
1295       {
1296         mySelIter->NextSelected();
1297         break;
1298       }
1299     }
1300     initCurrent();
1301   }
1302
1303 private:
1304
1305   void initCurrent()
1306   {
1307     switch (mySource)
1308     {
1309       case IterSource_All:
1310       {
1311         if (myMapIter.More())
1312         {
1313           myCurrentName = myMapIter.Key2();
1314           myCurrentTrs  = myMapIter.Key1();
1315           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1316         }
1317         break;
1318       }
1319       case IterSource_List:
1320       {
1321         if (mySeqIter.More())
1322         {
1323           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1324           {
1325             std::cout << "Error: object " << mySeqIter.Value() << " is not displayed!\n";
1326             return;
1327           }
1328           myCurrentName = mySeqIter.Value();
1329           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1330           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1331         }
1332         break;
1333       }
1334       case IterSource_Selected:
1335       {
1336         if (mySelIter->MoreSelected())
1337         {
1338           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1339           myCurrent     = mySelIter->SelectedInteractive();
1340         }
1341         break;
1342       }
1343     }
1344   }
1345
1346 private:
1347
1348   enum IterSource
1349   {
1350     IterSource_All,
1351     IterSource_List,
1352     IterSource_Selected
1353   };
1354
1355 private:
1356
1357   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1358   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1359   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1360   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1361
1362   TCollection_AsciiString        myCurrentName;//!< current item name
1363   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1364   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1365
1366   IterSource                     mySource;     //!< iterated collection
1367
1368 };
1369
1370 //==============================================================================
1371 //function : VInteriorStyle
1372 //purpose  : sets interior style of the a selected or named or displayed shape
1373 //==============================================================================
1374 static int VSetInteriorStyle (Draw_Interpretor& theDI,
1375                               Standard_Integer  theArgNb,
1376                               const char**      theArgVec)
1377 {
1378   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1379   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1380   if (aCtx.IsNull())
1381   {
1382     std::cerr << "Error: no active view!\n";
1383     return 1;
1384   }
1385
1386   Standard_Integer anArgIter = 1;
1387   for (; anArgIter < theArgNb; ++anArgIter)
1388   {
1389     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
1390     {
1391       break;
1392     }
1393   }
1394   TCollection_AsciiString aName;
1395   if (theArgNb - anArgIter == 2)
1396   {
1397     aName = theArgVec[anArgIter++];
1398   }
1399   else if (theArgNb - anArgIter != 1)
1400   {
1401     std::cout << "Error: wrong number of arguments! See usage:\n";
1402     theDI.PrintHelp (theArgVec[0]);
1403     return 1;
1404   }
1405   Standard_Integer        anInterStyle = Aspect_IS_SOLID;
1406   TCollection_AsciiString aStyleArg (theArgVec[anArgIter++]);
1407   aStyleArg.LowerCase();
1408   if (aStyleArg == "empty")
1409   {
1410     anInterStyle = 0;
1411   }
1412   else if (aStyleArg == "hollow")
1413   {
1414     anInterStyle = 1;
1415   }
1416   else if (aStyleArg == "hatch")
1417   {
1418     anInterStyle = 2;
1419   }
1420   else if (aStyleArg == "solid")
1421   {
1422     anInterStyle = 3;
1423   }
1424   else if (aStyleArg == "hiddenline")
1425   {
1426     anInterStyle = 4;
1427   }
1428   else
1429   {
1430     anInterStyle = aStyleArg.IntegerValue();
1431   }
1432   if (anInterStyle < Aspect_IS_EMPTY
1433    || anInterStyle > Aspect_IS_HIDDENLINE)
1434   {
1435     std::cout << "Error: style must be within a range [0 (Aspect_IS_EMPTY), "
1436               << Aspect_IS_HIDDENLINE << " (Aspect_IS_HIDDENLINE)]\n";
1437     return 1;
1438   }
1439
1440   if (!aName.IsEmpty()
1441    && !GetMapOfAIS().IsBound2 (aName))
1442   {
1443     std::cout << "Error: object " << aName << " is not displayed!\n";
1444     return 1;
1445   }
1446
1447   if (aCtx->HasOpenedContext())
1448   {
1449     aCtx->CloseLocalContext();
1450   }
1451   for (ViewTest_PrsIter anIter (aName); anIter.More(); anIter.Next())
1452   {
1453     const Handle(AIS_InteractiveObject)& anIO = anIter.Current();
1454     if (!anIO.IsNull())
1455     {
1456       const Handle(Prs3d_Drawer)& aDrawer        = anIO->Attributes();
1457       Handle(Prs3d_ShadingAspect) aShadingAspect = aDrawer->ShadingAspect();
1458       Handle(Graphic3d_AspectFillArea3d) aFillAspect = aShadingAspect->Aspect();
1459       aFillAspect->SetInteriorStyle ((Aspect_InteriorStyle )anInterStyle);
1460       aCtx->RecomputePrsOnly (anIO, Standard_False, Standard_True);
1461     }
1462   }
1463   return 0;
1464 }
1465
1466 //! Auxiliary structure for VAspects
1467 struct ViewerTest_AspectsChangeSet
1468 {
1469   Standard_Integer         ToSetVisibility;
1470   Standard_Integer         Visibility;
1471
1472   Standard_Integer         ToSetColor;
1473   Quantity_Color           Color;
1474
1475   Standard_Integer         ToSetLineWidth;
1476   Standard_Real            LineWidth;
1477
1478   Standard_Integer         ToSetTypeOfLine;
1479   Aspect_TypeOfLine        TypeOfLine;
1480
1481   Standard_Integer         ToSetTransparency;
1482   Standard_Real            Transparency;
1483
1484   Standard_Integer         ToSetMaterial;
1485   Graphic3d_NameOfMaterial Material;
1486   TCollection_AsciiString  MatName;
1487
1488   NCollection_Sequence<TopoDS_Shape> SubShapes;
1489
1490   Standard_Integer         ToSetShowFreeBoundary;
1491   Standard_Integer         ToSetFreeBoundaryWidth;
1492   Standard_Real            FreeBoundaryWidth;
1493   Standard_Integer         ToSetFreeBoundaryColor;
1494   Quantity_Color           FreeBoundaryColor;
1495
1496   Standard_Integer         ToEnableIsoOnTriangulation;
1497
1498   Standard_Integer         ToSetMaxParamValue;
1499   Standard_Real            MaxParamValue;
1500
1501   Standard_Integer         ToSetSensitivity;
1502   Standard_Integer         SelectionMode;
1503   Standard_Integer         Sensitivity;
1504
1505   //! Empty constructor
1506   ViewerTest_AspectsChangeSet()
1507   : ToSetVisibility   (0),
1508     Visibility        (1),
1509     ToSetColor        (0),
1510     Color             (DEFAULT_COLOR),
1511     ToSetLineWidth    (0),
1512     LineWidth         (1.0),
1513     ToSetTypeOfLine   (0),
1514     TypeOfLine        (Aspect_TOL_SOLID),
1515     ToSetTransparency (0),
1516     Transparency      (0.0),
1517     ToSetMaterial     (0),
1518     Material          (Graphic3d_NOM_DEFAULT),
1519     ToSetShowFreeBoundary      (0),
1520     ToSetFreeBoundaryWidth     (0),
1521     FreeBoundaryWidth          (1.0),
1522     ToSetFreeBoundaryColor     (0),
1523     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1524     ToEnableIsoOnTriangulation (-1),
1525     ToSetMaxParamValue (0),
1526     MaxParamValue (500000),
1527     ToSetSensitivity (0),
1528     SelectionMode (-1),
1529     Sensitivity (-1) {}
1530
1531   //! @return true if no changes have been requested
1532   Standard_Boolean IsEmpty() const
1533   {
1534     return ToSetVisibility        == 0
1535         && ToSetLineWidth         == 0
1536         && ToSetTransparency      == 0
1537         && ToSetColor             == 0
1538         && ToSetMaterial          == 0
1539         && ToSetShowFreeBoundary  == 0
1540         && ToSetFreeBoundaryColor == 0
1541         && ToSetFreeBoundaryWidth == 0
1542         && ToSetMaxParamValue     == 0
1543         && ToSetSensitivity       == 0;
1544   }
1545
1546   //! @return true if properties are valid
1547   Standard_Boolean Validate (const Standard_Boolean theIsSubPart) const
1548   {
1549     Standard_Boolean isOk = Standard_True;
1550     if (Visibility != 0 && Visibility != 1)
1551     {
1552       std::cout << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")\n";
1553       isOk = Standard_False;
1554     }
1555     if (LineWidth <= 0.0
1556      || LineWidth >  10.0)
1557     {
1558       std::cout << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")\n";
1559       isOk = Standard_False;
1560     }
1561     if (Transparency < 0.0
1562      || Transparency > 1.0)
1563     {
1564       std::cout << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")\n";
1565       isOk = Standard_False;
1566     }
1567     if (theIsSubPart
1568      && ToSetTransparency)
1569     {
1570       std::cout << "Error: the transparency can not be defined for sub-part of object!\n";
1571       isOk = Standard_False;
1572     }
1573     if (ToSetMaterial == 1
1574      && Material == Graphic3d_NOM_DEFAULT)
1575     {
1576       std::cout << "Error: unknown material " << MatName << ".\n";
1577       isOk = Standard_False;
1578     }
1579     if (FreeBoundaryWidth <= 0.0
1580      || FreeBoundaryWidth >  10.0)
1581     {
1582       std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
1583       isOk = Standard_False;
1584     }
1585     if (MaxParamValue < 0.0)
1586     {
1587       std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n";
1588       isOk = Standard_False;
1589     }
1590     if (Sensitivity <= 0 && ToSetSensitivity)
1591     {
1592       std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
1593       isOk = Standard_False;
1594     }
1595     return isOk;
1596   }
1597
1598 };
1599
1600 //==============================================================================
1601 //function : VAspects
1602 //purpose  :
1603 //==============================================================================
1604 static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
1605                                   Standard_Integer  theArgNb,
1606                                   const char**      theArgVec)
1607 {
1608   TCollection_AsciiString aCmdName (theArgVec[0]);
1609   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
1610   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
1611   if (aCtx.IsNull())
1612   {
1613     std::cerr << "Error: no active view!\n";
1614     return 1;
1615   }
1616
1617   Standard_Integer anArgIter = 1;
1618   Standard_Boolean isDefaults = Standard_False;
1619   NCollection_Sequence<TCollection_AsciiString> aNames;
1620   for (; anArgIter < theArgNb; ++anArgIter)
1621   {
1622     TCollection_AsciiString anArg = theArgVec[anArgIter];
1623     if (anUpdateTool.parseRedrawMode (anArg))
1624     {
1625       continue;
1626     }
1627     else if (!anArg.IsEmpty()
1628            && anArg.Value (1) != '-')
1629     {
1630       aNames.Append (anArg);
1631     }
1632     else
1633     {
1634       if (anArg == "-defaults")
1635       {
1636         isDefaults = Standard_True;
1637         ++anArgIter;
1638       }
1639       break;
1640     }
1641   }
1642
1643   if (!aNames.IsEmpty() && isDefaults)
1644   {
1645     std::cout << "Error: wrong syntax. If -defaults is used there should not be any objects' names!\n";
1646     return 1;
1647   }
1648
1649   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
1650   aChanges.Append (ViewerTest_AspectsChangeSet());
1651   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
1652
1653   // parse syntax of legacy commands
1654   if (aCmdName == "vsetwidth")
1655   {
1656     if (aNames.IsEmpty()
1657     || !aNames.Last().IsRealValue())
1658     {
1659       std::cout << "Error: not enough arguments!\n";
1660       return 1;
1661     }
1662     aChangeSet->ToSetLineWidth = 1;
1663     aChangeSet->LineWidth = aNames.Last().RealValue();
1664     aNames.Remove (aNames.Length());
1665   }
1666   else if (aCmdName == "vunsetwidth")
1667   {
1668     aChangeSet->ToSetLineWidth = -1;
1669   }
1670   else if (aCmdName == "vsetcolor")
1671   {
1672     if (aNames.IsEmpty())
1673     {
1674       std::cout << "Error: not enough arguments!\n";
1675       return 1;
1676     }
1677     aChangeSet->ToSetColor = 1;
1678
1679     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
1680     Standard_Boolean     isOk   = Standard_False;
1681     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
1682     {
1683       aChangeSet->Color = aColor;
1684       aNames.Remove (aNames.Length());
1685       isOk = Standard_True;
1686     }
1687     else if (aNames.Length() >= 3)
1688     {
1689       const TCollection_AsciiString anRgbStr[3] =
1690       {
1691         aNames.Value (aNames.Upper() - 2),
1692         aNames.Value (aNames.Upper() - 1),
1693         aNames.Value (aNames.Upper() - 0)
1694       };
1695       isOk = anRgbStr[0].IsRealValue()
1696           && anRgbStr[1].IsRealValue()
1697           && anRgbStr[2].IsRealValue();
1698       if (isOk)
1699       {
1700         Graphic3d_Vec4d anRgb;
1701         anRgb.x() = anRgbStr[0].RealValue();
1702         anRgb.y() = anRgbStr[1].RealValue();
1703         anRgb.z() = anRgbStr[2].RealValue();
1704         if (anRgb.x() < 0.0 || anRgb.x() > 1.0
1705          || anRgb.y() < 0.0 || anRgb.y() > 1.0
1706          || anRgb.z() < 0.0 || anRgb.z() > 1.0)
1707         {
1708           std::cout << "Error: RGB color values should be within range 0..1!\n";
1709           return 1;
1710         }
1711         aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
1712         aNames.Remove (aNames.Length());
1713         aNames.Remove (aNames.Length());
1714         aNames.Remove (aNames.Length());
1715       }
1716     }
1717     if (!isOk)
1718     {
1719       std::cout << "Error: not enough arguments!\n";
1720       return 1;
1721     }
1722   }
1723   else if (aCmdName == "vunsetcolor")
1724   {
1725     aChangeSet->ToSetColor = -1;
1726   }
1727   else if (aCmdName == "vsettransparency")
1728   {
1729     if (aNames.IsEmpty()
1730     || !aNames.Last().IsRealValue())
1731     {
1732       std::cout << "Error: not enough arguments!\n";
1733       return 1;
1734     }
1735     aChangeSet->ToSetTransparency = 1;
1736     aChangeSet->Transparency  = aNames.Last().RealValue();
1737     aNames.Remove (aNames.Length());
1738   }
1739   else if (aCmdName == "vunsettransparency")
1740   {
1741     aChangeSet->ToSetTransparency = -1;
1742   }
1743   else if (aCmdName == "vsetmaterial")
1744   {
1745     if (aNames.IsEmpty())
1746     {
1747       std::cout << "Error: not enough arguments!\n";
1748       return 1;
1749     }
1750     aChangeSet->ToSetMaterial = 1;
1751     aChangeSet->MatName  = aNames.Last();
1752     aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1753     aNames.Remove (aNames.Length());
1754   }
1755   else if (aCmdName == "vunsetmaterial")
1756   {
1757     aChangeSet->ToSetMaterial = -1;
1758   }
1759   else if (anArgIter >= theArgNb)
1760   {
1761     std::cout << "Error: not enough arguments!\n";
1762     return 1;
1763   }
1764
1765   if (!aChangeSet->IsEmpty())
1766   {
1767     anArgIter = theArgNb;
1768   }
1769   for (; anArgIter < theArgNb; ++anArgIter)
1770   {
1771     TCollection_AsciiString anArg = theArgVec[anArgIter];
1772     anArg.LowerCase();
1773     if (anArg == "-setwidth"
1774      || anArg == "-setlinewidth")
1775     {
1776       if (++anArgIter >= theArgNb)
1777       {
1778         std::cout << "Error: wrong syntax at " << anArg << "\n";
1779         return 1;
1780       }
1781       aChangeSet->ToSetLineWidth = 1;
1782       aChangeSet->LineWidth = Draw::Atof (theArgVec[anArgIter]);
1783     }
1784     else if (anArg == "-unsetwidth"
1785           || anArg == "-unsetlinewidth")
1786     {
1787       aChangeSet->ToSetLineWidth = -1;
1788       aChangeSet->LineWidth = 1.0;
1789     }
1790     else if (anArg == "-settransp"
1791           || anArg == "-settransparency")
1792     {
1793       if (++anArgIter >= theArgNb)
1794       {
1795         std::cout << "Error: wrong syntax at " << anArg << "\n";
1796         return 1;
1797       }
1798       aChangeSet->ToSetTransparency = 1;
1799       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
1800       if (aChangeSet->Transparency >= 0.0
1801        && aChangeSet->Transparency <= Precision::Confusion())
1802       {
1803         aChangeSet->ToSetTransparency = -1;
1804         aChangeSet->Transparency = 0.0;
1805       }
1806     }
1807     else if (anArg == "-setvis"
1808           || anArg == "-setvisibility")
1809     {
1810       if (++anArgIter >= theArgNb)
1811       {
1812         std::cout << "Error: wrong syntax at " << anArg << "\n";
1813         return 1;
1814       }
1815
1816       aChangeSet->ToSetVisibility = 1;
1817       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
1818     }
1819     else if (anArg == "-setalpha")
1820     {
1821       if (++anArgIter >= theArgNb)
1822       {
1823         std::cout << "Error: wrong syntax at " << anArg << "\n";
1824         return 1;
1825       }
1826       aChangeSet->ToSetTransparency = 1;
1827       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
1828       if (aChangeSet->Transparency < 0.0
1829        || aChangeSet->Transparency > 1.0)
1830       {
1831         std::cout << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")\n";
1832         return 1;
1833       }
1834       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
1835       if (aChangeSet->Transparency >= 0.0
1836        && aChangeSet->Transparency <= Precision::Confusion())
1837       {
1838         aChangeSet->ToSetTransparency = -1;
1839         aChangeSet->Transparency = 0.0;
1840       }
1841     }
1842     else if (anArg == "-unsettransp"
1843           || anArg == "-unsettransparency"
1844           || anArg == "-unsetalpha"
1845           || anArg == "-opaque")
1846     {
1847       aChangeSet->ToSetTransparency = -1;
1848       aChangeSet->Transparency = 0.0;
1849     }
1850     else if (anArg == "-setcolor")
1851     {
1852       Standard_Integer aNbComps  = 0;
1853       Standard_Integer aCompIter = anArgIter + 1;
1854       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
1855       {
1856         if (theArgVec[aCompIter][0] == '-')
1857         {
1858           break;
1859         }
1860       }
1861       switch (aNbComps)
1862       {
1863         case 1:
1864         {
1865           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
1866           Standard_CString     aName  = theArgVec[anArgIter + 1];
1867           if (!Quantity_Color::ColorFromName (aName, aColor))
1868           {
1869             std::cout << "Error: unknown color name '" << aName << "'\n";
1870             return 1;
1871           }
1872           aChangeSet->Color = aColor;
1873           break;
1874         }
1875         case 3:
1876         {
1877           Graphic3d_Vec3d anRgb;
1878           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
1879           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
1880           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
1881           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
1882            || anRgb.y() < 0.0 || anRgb.y() > 1.0
1883            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
1884           {
1885             std::cout << "Error: RGB color values should be within range 0..1!\n";
1886             return 1;
1887           }
1888           aChangeSet->Color.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
1889           break;
1890         }
1891         default:
1892         {
1893           std::cout << "Error: wrong syntax at " << anArg << "\n";
1894           return 1;
1895         }
1896       }
1897       aChangeSet->ToSetColor = 1;
1898       anArgIter += aNbComps;
1899     }
1900     else if (anArg == "-setlinetype")
1901     {
1902       if (++anArgIter >= theArgNb)
1903       {
1904         std::cout << "Error: wrong syntax at " << anArg << "\n";
1905         return 1;
1906       }
1907
1908       TCollection_AsciiString aValue (theArgVec[anArgIter]);
1909       aValue.LowerCase();
1910
1911       if (aValue.IsEqual ("solid"))
1912       {
1913         aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
1914       }
1915       else if (aValue.IsEqual ("dot"))
1916       {
1917         aChangeSet->TypeOfLine = Aspect_TOL_DOT;
1918       }
1919       else if (aValue.IsEqual ("dash"))
1920       {
1921         aChangeSet->TypeOfLine = Aspect_TOL_DASH;
1922       }
1923       else if (aValue.IsEqual ("dotdash"))
1924       {
1925         aChangeSet->TypeOfLine = Aspect_TOL_DOTDASH;
1926       }
1927       else
1928       {
1929         std::cout << "Error: wrong syntax at " << anArg << "\n";
1930         return 1;
1931       }
1932
1933       aChangeSet->ToSetTypeOfLine = 1;
1934     }
1935     else if (anArg == "-unsetlinetype")
1936     {
1937       aChangeSet->ToSetTypeOfLine = -1;
1938     }
1939     else if (anArg == "-unsetcolor")
1940     {
1941       aChangeSet->ToSetColor = -1;
1942       aChangeSet->Color = DEFAULT_COLOR;
1943     }
1944     else if (anArg == "-setmat"
1945           || anArg == "-setmaterial")
1946     {
1947       if (++anArgIter >= theArgNb)
1948       {
1949         std::cout << "Error: wrong syntax at " << anArg << "\n";
1950         return 1;
1951       }
1952       aChangeSet->ToSetMaterial = 1;
1953       aChangeSet->MatName  = theArgVec[anArgIter];
1954       aChangeSet->Material = Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString());
1955     }
1956     else if (anArg == "-unsetmat"
1957           || anArg == "-unsetmaterial")
1958     {
1959       aChangeSet->ToSetMaterial = -1;
1960       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
1961     }
1962     else if (anArg == "-subshape"
1963           || anArg == "-subshapes")
1964     {
1965       if (isDefaults)
1966       {
1967         std::cout << "Error: wrong syntax. -subshapes can not be used together with -defaults call!\n";
1968         return 1;
1969       }
1970
1971       if (aNames.IsEmpty())
1972       {
1973         std::cout << "Error: main objects should specified explicitly when -subshapes is used!\n";
1974         return 1;
1975       }
1976
1977       aChanges.Append (ViewerTest_AspectsChangeSet());
1978       aChangeSet = &aChanges.ChangeLast();
1979
1980       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
1981       {
1982         Standard_CString aSubShapeName = theArgVec[anArgIter];
1983         if (*aSubShapeName == '-')
1984         {
1985           --anArgIter;
1986           break;
1987         }
1988
1989         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
1990         if (aSubShape.IsNull())
1991         {
1992           std::cerr << "Error: shape " << aSubShapeName << " doesn't found!\n";
1993           return 1;
1994         }
1995         aChangeSet->SubShapes.Append (aSubShape);
1996       }
1997
1998       if (aChangeSet->SubShapes.IsEmpty())
1999       {
2000         std::cerr << "Error: empty list is specified after -subshapes!\n";
2001         return 1;
2002       }
2003     }
2004     else if (anArg == "-freeboundary"
2005           || anArg == "-fb")
2006     {
2007       if (++anArgIter >= theArgNb)
2008       {
2009         std::cout << "Error: wrong syntax at " << anArg << "\n";
2010         return 1;
2011       }
2012       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2013       aValue.LowerCase();
2014       if (aValue == "on"
2015        || aValue == "1")
2016       {
2017         aChangeSet->ToSetShowFreeBoundary = 1;
2018       }
2019       else if (aValue == "off"
2020             || aValue == "0")
2021       {
2022         aChangeSet->ToSetShowFreeBoundary = -1;
2023       }
2024       else
2025       {
2026         std::cout << "Error: wrong syntax at " << anArg << "\n";
2027         return 1;
2028       }
2029     }
2030     else if (anArg == "-setfreeboundarywidth"
2031           || anArg == "-setfbwidth")
2032     {
2033       if (++anArgIter >= theArgNb)
2034       {
2035         std::cout << "Error: wrong syntax at " << anArg << "\n";
2036         return 1;
2037       }
2038       aChangeSet->ToSetFreeBoundaryWidth = 1;
2039       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2040     }
2041     else if (anArg == "-unsetfreeboundarywidth"
2042           || anArg == "-unsetfbwidth")
2043     {
2044       aChangeSet->ToSetFreeBoundaryWidth = -1;
2045       aChangeSet->FreeBoundaryWidth = 1.0;
2046     }
2047     else if (anArg == "-setfreeboundarycolor"
2048           || anArg == "-setfbcolor")
2049     {
2050       Standard_Integer aNbComps  = 0;
2051       Standard_Integer aCompIter = anArgIter + 1;
2052       for (; aCompIter < theArgNb; ++aCompIter, ++aNbComps)
2053       {
2054         if (theArgVec[aCompIter][0] == '-')
2055         {
2056           break;
2057         }
2058       }
2059       switch (aNbComps)
2060       {
2061         case 1:
2062         {
2063           Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2064           Standard_CString     aName  = theArgVec[anArgIter + 1];
2065           if (!Quantity_Color::ColorFromName (aName, aColor))
2066           {
2067             std::cout << "Error: unknown free boundary color name '" << aName << "'\n";
2068             return 1;
2069           }
2070           aChangeSet->FreeBoundaryColor = aColor;
2071           break;
2072         }
2073         case 3:
2074         {
2075           Graphic3d_Vec3d anRgb;
2076           anRgb.x() = Draw::Atof (theArgVec[anArgIter + 1]);
2077           anRgb.y() = Draw::Atof (theArgVec[anArgIter + 2]);
2078           anRgb.z() = Draw::Atof (theArgVec[anArgIter + 3]);
2079           if (anRgb.x() < 0.0 || anRgb.x() > 1.0
2080            || anRgb.y() < 0.0 || anRgb.y() > 1.0
2081            || anRgb.z() < 0.0 || anRgb.z() > 1.0)
2082           {
2083             std::cout << "Error: free boundary RGB color values should be within range 0..1!\n";
2084             return 1;
2085           }
2086           aChangeSet->FreeBoundaryColor.SetValues (anRgb.x(), anRgb.y(), anRgb.z(), Quantity_TOC_RGB);
2087           break;
2088         }
2089         default:
2090         {
2091           std::cout << "Error: wrong syntax at " << anArg << "\n";
2092           return 1;
2093         }
2094       }
2095       aChangeSet->ToSetFreeBoundaryColor = 1;
2096       anArgIter += aNbComps;
2097     }
2098     else if (anArg == "-unsetfreeboundarycolor"
2099           || anArg == "-unsetfbcolor")
2100     {
2101       aChangeSet->ToSetFreeBoundaryColor = -1;
2102       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2103     }
2104     else if (anArg == "-unset")
2105     {
2106       aChangeSet->ToSetVisibility = 1;
2107       aChangeSet->Visibility = 1;
2108       aChangeSet->ToSetLineWidth = -1;
2109       aChangeSet->LineWidth = 1.0;
2110       aChangeSet->ToSetTypeOfLine = -1;
2111       aChangeSet->TypeOfLine = Aspect_TOL_SOLID;
2112       aChangeSet->ToSetTransparency = -1;
2113       aChangeSet->Transparency = 0.0;
2114       aChangeSet->ToSetColor = -1;
2115       aChangeSet->Color = DEFAULT_COLOR;
2116       aChangeSet->ToSetMaterial = -1;
2117       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2118       aChangeSet->ToSetShowFreeBoundary = -1;
2119       aChangeSet->ToSetFreeBoundaryColor = -1;
2120       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2121       aChangeSet->ToSetFreeBoundaryWidth = -1;
2122       aChangeSet->FreeBoundaryWidth = 1.0;
2123     }
2124     else if (anArg == "-isoontriangulation"
2125           || anArg == "-isoontriang")
2126     {
2127       if (++anArgIter >= theArgNb)
2128       {
2129         std::cout << "Error: wrong syntax at " << anArg << "\n";
2130         return 1;
2131       }
2132       TCollection_AsciiString aValue (theArgVec[anArgIter]);
2133       aValue.LowerCase();
2134       if (aValue == "on"
2135         || aValue == "1")
2136       {
2137         aChangeSet->ToEnableIsoOnTriangulation = 1;
2138       }
2139       else if (aValue == "off"
2140         || aValue == "0")
2141       {
2142         aChangeSet->ToEnableIsoOnTriangulation = 0;
2143       }
2144       else
2145       {
2146         std::cout << "Error: wrong syntax at " << anArg << "\n";
2147         return 1;
2148       }
2149     }
2150     else if (anArg == "-setmaxparamvalue")
2151     {
2152       if (++anArgIter >= theArgNb)
2153       {
2154         std::cout << "Error: wrong syntax at " << anArg << "\n";
2155         return 1;
2156       }
2157       aChangeSet->ToSetMaxParamValue = 1;
2158       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
2159     }
2160     else if (anArg == "-setsensitivity")
2161     {
2162       if (isDefaults)
2163       {
2164         std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
2165         return 1;
2166       }
2167
2168       if (aNames.IsEmpty())
2169       {
2170         std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
2171         return 1;
2172       }
2173
2174       if (anArgIter + 2 >= theArgNb)
2175       {
2176         std::cout << "Error: wrong syntax at " << anArg << "\n";
2177         return 1;
2178       }
2179       aChangeSet->ToSetSensitivity = 1;
2180       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
2181       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
2182     }
2183     else
2184     {
2185       std::cout << "Error: wrong syntax at " << anArg << "\n";
2186       return 1;
2187     }
2188   }
2189
2190   Standard_Boolean isFirst = Standard_True;
2191   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2192        aChangesIter.More(); aChangesIter.Next())
2193   {
2194     if (!aChangesIter.Value().Validate (!isFirst))
2195     {
2196       return 1;
2197     }
2198     isFirst = Standard_False;
2199   }
2200
2201   if (aCtx->HasOpenedContext())
2202   {
2203     aCtx->CloseLocalContext();
2204   }
2205
2206   // special case for -defaults parameter.
2207   // all changed values will be set to DefaultDrawer.
2208   if (isDefaults)
2209   {
2210     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
2211
2212     if (aChangeSet->ToSetLineWidth != 0)
2213     {
2214       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
2215       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
2216       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
2217       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
2218     }
2219     if (aChangeSet->ToSetColor != 0)
2220     {
2221       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
2222       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
2223       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
2224       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
2225       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
2226       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
2227     }
2228     if (aChangeSet->ToSetTypeOfLine != 0)
2229     {
2230       aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2231       aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2232       aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2233       aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2234       aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2235     }
2236     if (aChangeSet->ToSetTransparency != 0)
2237     {
2238       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
2239     }
2240     if (aChangeSet->ToSetMaterial != 0)
2241     {
2242       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
2243     }
2244     if (aChangeSet->ToSetShowFreeBoundary == 1)
2245     {
2246       aDrawer->SetFreeBoundaryDraw (Standard_True);
2247     }
2248     else if (aChangeSet->ToSetShowFreeBoundary == -1)
2249     {
2250       aDrawer->SetFreeBoundaryDraw (Standard_False);
2251     }
2252     if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2253     {
2254       aDrawer->FreeBoundaryAspect()->SetWidth (aChangeSet->FreeBoundaryWidth);
2255     }
2256     if (aChangeSet->ToSetFreeBoundaryColor != 0)
2257     {
2258       aDrawer->FreeBoundaryAspect()->SetColor (aChangeSet->FreeBoundaryColor);
2259     }
2260     if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2261     {
2262       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
2263     }
2264     if (aChangeSet->ToSetMaxParamValue != 0)
2265     {
2266       aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2267     }
2268
2269     // redisplay all objects in context
2270     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2271     {
2272       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
2273       if (!aPrs.IsNull())
2274       {
2275         aCtx->Redisplay (aPrs, Standard_False);
2276       }
2277     }
2278     return 0;
2279   }
2280
2281   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
2282   {
2283     const TCollection_AsciiString& aName   = aPrsIter.CurrentName();
2284     Handle(AIS_InteractiveObject)  aPrs    = aPrsIter.Current();
2285     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
2286     Handle(AIS_ColoredShape) aColoredPrs;
2287     Standard_Boolean toDisplay = Standard_False;
2288     Standard_Boolean toRedisplay = Standard_False;
2289     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
2290     {
2291       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
2292       if (aShapePrs.IsNull())
2293       {
2294         std::cout << "Error: an object " << aName << " is not an AIS_Shape presentation!\n";
2295         return 1;
2296       }
2297       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
2298       if (aColoredPrs.IsNull())
2299       {
2300         aColoredPrs = new AIS_ColoredShape (aShapePrs);
2301         aCtx->Remove (aShapePrs, Standard_False);
2302         GetMapOfAIS().UnBind2 (aName);
2303         GetMapOfAIS().Bind (aColoredPrs, aName);
2304         toDisplay = Standard_True;
2305         aShapePrs = aColoredPrs;
2306         aPrs      = aColoredPrs;
2307       }
2308     }
2309
2310     if (!aPrs.IsNull())
2311     {
2312       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
2313       aChangeSet = &aChangesIter.ChangeValue();
2314       if (aChangeSet->ToSetVisibility == 1)
2315       {
2316         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
2317         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
2318       }
2319       else if (aChangeSet->ToSetMaterial == 1)
2320       {
2321         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
2322       }
2323       else if (aChangeSet->ToSetMaterial == -1)
2324       {
2325         aCtx->UnsetMaterial (aPrs, Standard_False);
2326       }
2327       if (aChangeSet->ToSetColor == 1)
2328       {
2329         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
2330       }
2331       else if (aChangeSet->ToSetColor == -1)
2332       {
2333         aCtx->UnsetColor (aPrs, Standard_False);
2334       }
2335       if (aChangeSet->ToSetTransparency == 1)
2336       {
2337         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
2338       }
2339       else if (aChangeSet->ToSetTransparency == -1)
2340       {
2341         aCtx->UnsetTransparency (aPrs, Standard_False);
2342       }
2343       if (aChangeSet->ToSetLineWidth == 1)
2344       {
2345         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
2346       }
2347       else if (aChangeSet->ToSetLineWidth == -1)
2348       {
2349         aCtx->UnsetWidth (aPrs, Standard_False);
2350       }
2351       else if (aChangeSet->ToEnableIsoOnTriangulation != -1)
2352       {
2353         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
2354         toRedisplay = Standard_True;
2355       }
2356       else if (aChangeSet->ToSetSensitivity != 0)
2357       {
2358         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2359       }
2360       if (!aDrawer.IsNull())
2361       {
2362         if (aChangeSet->ToSetShowFreeBoundary == 1)
2363         {
2364           aDrawer->SetFreeBoundaryDraw (Standard_True);
2365           toRedisplay = Standard_True;
2366         }
2367         else if (aChangeSet->ToSetShowFreeBoundary == -1)
2368         {
2369           aDrawer->SetFreeBoundaryDraw (Standard_False);
2370           toRedisplay = Standard_True;
2371         }
2372         if (aChangeSet->ToSetFreeBoundaryWidth != 0)
2373         {
2374           Handle(Prs3d_LineAspect) aBoundaryAspect =
2375               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2376           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2377           aBoundaryAspect->SetWidth (aChangeSet->FreeBoundaryWidth);
2378           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2379           toRedisplay = Standard_True;
2380         }
2381         if (aChangeSet->ToSetFreeBoundaryColor != 0)
2382         {
2383           Handle(Prs3d_LineAspect) aBoundaryAspect =
2384               new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
2385           *aBoundaryAspect->Aspect() = *aDrawer->FreeBoundaryAspect()->Aspect();
2386           aBoundaryAspect->SetColor (aChangeSet->FreeBoundaryColor);
2387           aDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
2388           toRedisplay = Standard_True;
2389         }
2390         if (aChangeSet->ToSetTypeOfLine != 0)
2391         {
2392           aDrawer->LineAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2393           aDrawer->WireAspect()->SetTypeOfLine           (aChangeSet->TypeOfLine);
2394           aDrawer->FreeBoundaryAspect()->SetTypeOfLine   (aChangeSet->TypeOfLine);
2395           aDrawer->UnFreeBoundaryAspect()->SetTypeOfLine (aChangeSet->TypeOfLine);
2396           aDrawer->SeenLineAspect()->SetTypeOfLine       (aChangeSet->TypeOfLine);
2397           toRedisplay = Standard_True;
2398         }
2399         if (aChangeSet->ToSetMaxParamValue != 0)
2400         {
2401           aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2402         }
2403       }
2404
2405       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
2406       {
2407         aChangeSet = &aChangesIter.ChangeValue();
2408         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
2409              aSubShapeIter.More(); aSubShapeIter.Next())
2410         {
2411           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
2412           if (aChangeSet->ToSetVisibility == 1)
2413           {
2414             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2415             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
2416           }
2417           if (aChangeSet->ToSetColor == 1)
2418           {
2419             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
2420           }
2421           if (aChangeSet->ToSetLineWidth == 1)
2422           {
2423             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
2424           }
2425           if (aChangeSet->ToSetColor     == -1
2426            || aChangeSet->ToSetLineWidth == -1)
2427           {
2428             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
2429           }
2430           if (aChangeSet->ToSetMaxParamValue != 0)
2431           {
2432             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
2433             aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue);
2434           }
2435           if (aChangeSet->ToSetSensitivity != 0)
2436           {
2437             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
2438           }
2439         }
2440       }
2441       if (toDisplay)
2442       {
2443         aCtx->Display (aPrs, Standard_False);
2444       }
2445       if (toRedisplay)
2446       {
2447         aCtx->Redisplay (aPrs, Standard_False);
2448       }
2449       else if (!aColoredPrs.IsNull())
2450       {
2451         aCtx->Redisplay (aColoredPrs, Standard_False);
2452       }
2453     }
2454   }
2455   return 0;
2456 }
2457
2458 //==============================================================================
2459 //function : VDonly2
2460 //author   : ege
2461 //purpose  : Display only a selected or named  object
2462 //           if there is no selected or named object s, nothing is done
2463 //==============================================================================
2464 static int VDonly2 (Draw_Interpretor& ,
2465                     Standard_Integer  theArgNb,
2466                     const char**      theArgVec)
2467 {
2468   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2469   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2470   if (aCtx.IsNull())
2471   {
2472     std::cerr << "Error: no active view!\n";
2473     return 1;
2474   }
2475
2476   if (aCtx->HasOpenedContext())
2477   {
2478     aCtx->CloseLocalContext();
2479   }
2480
2481   Standard_Integer anArgIter = 1;
2482   for (; anArgIter < theArgNb; ++anArgIter)
2483   {
2484     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
2485     {
2486       break;
2487     }
2488   }
2489
2490   NCollection_Map<Handle(Standard_Transient)> aDispSet;
2491   if (anArgIter >= theArgNb)
2492   {
2493     // display only selected objects
2494     if (aCtx->NbSelected() < 1)
2495     {
2496       return 0;
2497     }
2498
2499     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
2500     {
2501       aDispSet.Add (aCtx->SelectedInteractive());
2502     }
2503   }
2504   else
2505   {
2506     // display only specified objects
2507     for (; anArgIter < theArgNb; ++anArgIter)
2508     {
2509       TCollection_AsciiString aName = theArgVec[anArgIter];
2510       if (GetMapOfAIS().IsBound2 (aName))
2511       {
2512         const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2513         if (!aShape.IsNull())
2514         {
2515           aCtx->Display (aShape, Standard_False);
2516           aDispSet.Add (aShape);
2517         }
2518       }
2519     }
2520   }
2521
2522   // weed out other objects
2523   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
2524   {
2525     if (aDispSet.Contains (anIter.Key1()))
2526     {
2527       continue;
2528     }
2529
2530     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2531     if (aShape.IsNull())
2532     {
2533       aCtx->Erase (aShape, Standard_False);
2534     }
2535   }
2536   return 0;
2537 }
2538
2539 //==============================================================================
2540 //function : VRemove
2541 //purpose  : Removes selected or named objects.
2542 //           If there is no selected or named objects,
2543 //           all objects in the viewer can be removed with argument -all.
2544 //           If -context is in arguments, the object is not deleted from the map of
2545 //           objects (deleted only from the current context).
2546 //==============================================================================
2547 int VRemove (Draw_Interpretor& theDI,
2548              Standard_Integer  theArgNb,
2549              const char**      theArgVec)
2550 {
2551   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2552   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2553   if (aCtx.IsNull())
2554   {
2555     std::cerr << "Error: no active view!\n";
2556     return 1;
2557   }
2558
2559   Standard_Boolean isContextOnly = Standard_False;
2560   Standard_Boolean toRemoveAll   = Standard_False;
2561   Standard_Boolean toPrintInfo   = Standard_True;
2562   Standard_Boolean toRemoveLocal = Standard_False;
2563
2564   Standard_Integer anArgIter = 1;
2565   for (; anArgIter < theArgNb; ++anArgIter)
2566   {
2567     TCollection_AsciiString anArg = theArgVec[anArgIter];
2568     anArg.LowerCase();
2569     if (anArg == "-context")
2570     {
2571       isContextOnly = Standard_True;
2572     }
2573     else if (anArg == "-all")
2574     {
2575       toRemoveAll = Standard_True;
2576     }
2577     else if (anArg == "-noinfo")
2578     {
2579       toPrintInfo = Standard_False;
2580     }
2581     else if (anArg == "-local")
2582     {
2583       toRemoveLocal = Standard_True;
2584     }
2585     else if (anUpdateTool.parseRedrawMode (anArg))
2586     {
2587       continue;
2588     }
2589     else
2590     {
2591       break;
2592     }
2593   }
2594   if (toRemoveAll
2595    && anArgIter < theArgNb)
2596   {
2597     std::cerr << "Error: wrong syntax!\n";
2598     return 1;
2599   }
2600
2601   if (toRemoveLocal && !aCtx->HasOpenedContext())
2602   {
2603     std::cerr << "Error: local selection context is not open.\n";
2604     return 1;
2605   }
2606   else if (!toRemoveLocal && aCtx->HasOpenedContext())
2607   {
2608     aCtx->CloseAllContexts (Standard_False);
2609   }
2610
2611   NCollection_List<TCollection_AsciiString> anIONameList;
2612   if (toRemoveAll)
2613   {
2614     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2615          anIter.More(); anIter.Next())
2616     {
2617       anIONameList.Append (anIter.Key2());
2618     }
2619   }
2620   else if (anArgIter < theArgNb) // removed objects names are in argument list
2621   {
2622     for (; anArgIter < theArgNb; ++anArgIter)
2623     {
2624       TCollection_AsciiString aName = theArgVec[anArgIter];
2625       if (!GetMapOfAIS().IsBound2 (aName))
2626       {
2627         theDI << aName.ToCString() << " was not bound to some object.\n";
2628         continue;
2629       }
2630
2631       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2632       if (anIO->GetContext() != aCtx)
2633       {
2634         theDI << aName.ToCString() << " was not displayed in current context.\n";
2635         theDI << "Please activate view with this object displayed and try again.\n";
2636         continue;
2637       }
2638
2639       anIONameList.Append (aName);
2640       continue;
2641     }
2642   }
2643   else if (aCtx->NbSelected() > 0)
2644   {
2645     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2646          anIter.More(); anIter.Next())
2647     {
2648       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2649       if (!aCtx->IsSelected (anIO))
2650       {
2651         continue;
2652       }
2653
2654       anIONameList.Append (anIter.Key2());
2655       continue;
2656     }
2657   }
2658
2659   // Unbind all removed objects from the map of displayed IO.
2660   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
2661        anIter.More(); anIter.Next())
2662   {
2663     const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
2664     aCtx->Remove (anIO, Standard_False);
2665     if (toPrintInfo)
2666     {
2667       theDI << anIter.Value().ToCString() << " was removed\n";
2668     }
2669     if (!isContextOnly)
2670     {
2671       GetMapOfAIS().UnBind2 (anIter.Value());
2672     }
2673   }
2674
2675   // Close local context if it is empty
2676   TColStd_MapOfTransient aLocalIO;
2677   if (aCtx->HasOpenedContext()
2678    && !aCtx->LocalContext()->DisplayedObjects (aLocalIO))
2679   {
2680     aCtx->CloseAllContexts (Standard_False);
2681   }
2682
2683   return 0;
2684 }
2685
2686 //==============================================================================
2687 //function : VErase
2688 //purpose  : Erase some selected or named objects
2689 //           if there is no selected or named objects, the whole viewer is erased
2690 //==============================================================================
2691 int VErase (Draw_Interpretor& theDI,
2692             Standard_Integer  theArgNb,
2693             const char**      theArgVec)
2694 {
2695   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
2696   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
2697   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
2698   if (aCtx.IsNull())
2699   {
2700     std::cerr << "Error: no active view!\n";
2701     return 1;
2702   }
2703
2704   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
2705
2706   Standard_Integer anArgIter = 1;
2707   Standard_Boolean toEraseLocal  = Standard_False;
2708   Standard_Boolean toEraseInView = Standard_False;
2709   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
2710   for (; anArgIter < theArgNb; ++anArgIter)
2711   {
2712     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2713     anArgCase.LowerCase();
2714     if (anUpdateTool.parseRedrawMode (anArgCase))
2715     {
2716       continue;
2717     }
2718     else if (anArgCase == "-local")
2719     {
2720       toEraseLocal = Standard_True;
2721     }
2722     else if (anArgCase == "-view"
2723           || anArgCase == "-inview")
2724     {
2725       toEraseInView = Standard_True;
2726     }
2727     else
2728     {
2729       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
2730     }
2731   }
2732
2733   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
2734   {
2735     std::cerr << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.\n";
2736     return 1;
2737   }
2738
2739   if (toEraseLocal && !aCtx->HasOpenedContext())
2740   {
2741     std::cerr << "Error: local selection context is not open.\n";
2742     return 1;
2743   }
2744   else if (!toEraseLocal && aCtx->HasOpenedContext())
2745   {
2746     aCtx->CloseAllContexts (Standard_False);
2747   }
2748
2749   if (!aNamesOfEraseIO.IsEmpty())
2750   {
2751     // Erase named objects
2752     for (Standard_Integer anIter = 1; anIter <= aNamesOfEraseIO.Length(); ++anIter)
2753     {
2754       TCollection_AsciiString aName = aNamesOfEraseIO.Value (anIter);
2755       if (!GetMapOfAIS().IsBound2 (aName))
2756       {
2757         continue;
2758       }
2759
2760       const Handle(Standard_Transient)    anObj = GetMapOfAIS().Find2 (aName);
2761       const Handle(AIS_InteractiveObject) anIO  = Handle(AIS_InteractiveObject)::DownCast (anObj);
2762       theDI << aName.ToCString() << " ";
2763       if (!anIO.IsNull())
2764       {
2765         if (toEraseInView)
2766         {
2767           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2768         }
2769         else
2770         {
2771           aCtx->Erase (anIO, Standard_False);
2772         }
2773       }
2774     }
2775   }
2776   else if (!toEraseAll && aCtx->NbSelected() > 0)
2777   {
2778     // Erase selected objects
2779     const Standard_Boolean aHasOpenedContext = aCtx->HasOpenedContext();
2780     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2781          anIter.More(); anIter.Next())
2782     {
2783       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2784       if (!anIO.IsNull()
2785        && aCtx->IsSelected (anIO))
2786       {
2787         theDI << anIter.Key2().ToCString() << " ";
2788         if (toEraseInView)
2789         {
2790           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2791         }
2792         else if (aHasOpenedContext)
2793         {
2794           aCtx->Erase (anIO, Standard_False);
2795         }
2796       }
2797     }
2798
2799     if (!toEraseInView)
2800     {
2801       aCtx->EraseSelected (Standard_False);
2802     }
2803   }
2804   else
2805   {
2806     // Erase all objects
2807     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2808          anIter.More(); anIter.Next())
2809     {
2810       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2811       if (!anIO.IsNull())
2812       {
2813         if (toEraseInView)
2814         {
2815           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2816         }
2817         else
2818         {
2819           aCtx->Erase (anIO, Standard_False);
2820         }
2821       }
2822     }
2823   }
2824
2825   return 0;
2826 }
2827
2828 //==============================================================================
2829 //function : VDisplayAll
2830 //author   : ege
2831 //purpose  : Display all the objects of the Map
2832 //==============================================================================
2833 static int VDisplayAll (Draw_Interpretor& ,
2834                         Standard_Integer  theArgNb,
2835                         const char**      theArgVec)
2836
2837 {
2838   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2839   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2840   if (aCtx.IsNull())
2841   {
2842     std::cerr << "Error: no active view!\n";
2843     return 1;
2844   }
2845
2846   Standard_Integer anArgIter = 1;
2847   Standard_Boolean toDisplayLocal = Standard_False;
2848   for (; anArgIter < theArgNb; ++anArgIter)
2849   {
2850     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2851     anArgCase.LowerCase();
2852     if (anArgCase == "-local")
2853     {
2854       toDisplayLocal = Standard_True;
2855     }
2856     else if (anUpdateTool.parseRedrawMode (anArgCase))
2857     {
2858       continue;
2859     }
2860     else
2861     {
2862       break;
2863     }
2864   }
2865   if (anArgIter < theArgNb)
2866   {
2867     std::cout << theArgVec[0] << "Error: wrong syntax\n";
2868     return 1;
2869   }
2870
2871   if (toDisplayLocal && !aCtx->HasOpenedContext())
2872   {
2873     std::cerr << "Error: local selection context is not open.\n";
2874     return 1;
2875   }
2876   else if (!toDisplayLocal && aCtx->HasOpenedContext())
2877   {
2878     aCtx->CloseLocalContext (Standard_False);
2879   }
2880
2881   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2882        anIter.More(); anIter.Next())
2883   {
2884     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2885     aCtx->Erase (aShape, Standard_False);
2886   }
2887
2888   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2889        anIter.More(); anIter.Next())
2890   {
2891     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2892     aCtx->Display (aShape, Standard_False);
2893   }
2894   return 0;
2895 }
2896
2897 //! Auxiliary method to find presentation
2898 inline Handle(PrsMgr_Presentation) findPresentation (const Handle(AIS_InteractiveContext)& theCtx,
2899                                                      const Handle(AIS_InteractiveObject)&  theIO,
2900                                                      const Standard_Integer                theMode)
2901 {
2902   if (theIO.IsNull())
2903   {
2904     return Handle(PrsMgr_Presentation)();
2905   }
2906
2907   if (theMode != -1)
2908   {
2909     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
2910     {
2911       return theCtx->MainPrsMgr()->Presentation (theIO, theMode);
2912     }
2913   }
2914   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
2915   {
2916     return theCtx->MainPrsMgr()->Presentation (theIO, theIO->DisplayMode());
2917   }
2918   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
2919   {
2920     return theCtx->MainPrsMgr()->Presentation (theIO, theCtx->DisplayMode());
2921   }
2922   return Handle(PrsMgr_Presentation)();
2923 }
2924
2925 enum ViewerTest_BndAction
2926 {
2927   BndAction_Hide,
2928   BndAction_Show,
2929   BndAction_Print
2930 };
2931
2932 //! Auxiliary method to print bounding box of presentation
2933 inline void bndPresentation (Draw_Interpretor&                  theDI,
2934                              const Handle(PrsMgr_Presentation)& thePrs,
2935                              const TCollection_AsciiString&     theName,
2936                              const ViewerTest_BndAction         theAction)
2937 {
2938   switch (theAction)
2939   {
2940     case BndAction_Hide:
2941     {
2942       thePrs->Presentation()->GraphicUnHighlight();
2943       break;
2944     }
2945     case BndAction_Show:
2946     {
2947       Handle(Graphic3d_Structure) aPrs (thePrs->Presentation());
2948       aPrs->CStructure()->HighlightColor.r = 0.988235f;
2949       aPrs->CStructure()->HighlightColor.g = 0.988235f;
2950       aPrs->CStructure()->HighlightColor.b = 0.988235f;
2951       aPrs->CStructure()->HighlightWithBndBox (aPrs, Standard_True);
2952       break;
2953     }
2954     case BndAction_Print:
2955     {
2956       Bnd_Box aBox = thePrs->Presentation()->MinMaxValues();
2957       gp_Pnt aMin = aBox.CornerMin();
2958       gp_Pnt aMax = aBox.CornerMax();
2959       theDI << theName  << "\n"
2960             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
2961             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
2962       break;
2963     }
2964   }
2965 }
2966
2967 //==============================================================================
2968 //function : VBounding
2969 //purpose  :
2970 //==============================================================================
2971 int VBounding (Draw_Interpretor& theDI,
2972                Standard_Integer  theArgNb,
2973                const char**      theArgVec)
2974 {
2975   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2976   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2977   if (aCtx.IsNull())
2978   {
2979     std::cout << "Error: no active view!\n";
2980     return 1;
2981   }
2982
2983   ViewerTest_BndAction anAction = BndAction_Show;
2984   Standard_Integer     aMode    = -1;
2985
2986   Standard_Integer anArgIter = 1;
2987   for (; anArgIter < theArgNb; ++anArgIter)
2988   {
2989     TCollection_AsciiString anArg (theArgVec[anArgIter]);
2990     anArg.LowerCase();
2991     if (anArg == "-print")
2992     {
2993       anAction = BndAction_Print;
2994     }
2995     else if (anArg == "-show")
2996     {
2997       anAction = BndAction_Show;
2998     }
2999     else if (anArg == "-hide")
3000     {
3001       anAction = BndAction_Hide;
3002     }
3003     else if (anArg == "-mode")
3004     {
3005       if (++anArgIter >= theArgNb)
3006       {
3007         std::cout << "Error: wrong syntax at " << anArg << "\n";
3008         return 1;
3009       }
3010       aMode = Draw::Atoi (theArgVec[anArgIter]);
3011     }
3012     else if (!anUpdateTool.parseRedrawMode (anArg))
3013     {
3014       break;
3015     }
3016   }
3017
3018   if (anArgIter < theArgNb)
3019   {
3020     // has a list of names
3021     for (; anArgIter < theArgNb; ++anArgIter)
3022     {
3023       TCollection_AsciiString aName = theArgVec[anArgIter];
3024       if (!GetMapOfAIS().IsBound2 (aName))
3025       {
3026         std::cout << "Error: presentation " << aName << " does not exist\n";
3027         return 1;
3028       }
3029
3030       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
3031       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3032       if (aPrs.IsNull())
3033       {
3034         std::cout << "Error: presentation " << aName << " does not exist\n";
3035         return 1;
3036       }
3037       bndPresentation (theDI, aPrs, aName, anAction);
3038     }
3039   }
3040   else if (aCtx->NbSelected() > 0)
3041   {
3042     // remove all currently selected objects
3043     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3044     {
3045       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
3046       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3047       if (!aPrs.IsNull())
3048       {
3049         bndPresentation (theDI, aPrs, GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction);
3050       }
3051     }
3052   }
3053   else
3054   {
3055     // all objects
3056     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3057          anIter.More(); anIter.Next())
3058     {
3059       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
3060       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3061       if (!aPrs.IsNull())
3062       {
3063         bndPresentation (theDI, aPrs, anIter.Key2(), anAction);
3064       }
3065     }
3066   }
3067   return 0;
3068 }
3069
3070 //==============================================================================
3071 //function : VTexture
3072 //purpose  :
3073 //==============================================================================
3074 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgv)
3075 {
3076   TCollection_AsciiString aCommandName (theArgv[0]);
3077
3078   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
3079   if (aCommandName == "vtexture")
3080   {
3081     if (theArgsNb < 2)
3082     {
3083       std::cout << theArgv[0] << ":  invalid arguments.\n";
3084       std::cout << "Type help for more information.\n";
3085       return 1;
3086     }
3087
3088     // look for options of vtexture command
3089     TCollection_AsciiString aParseKey;
3090     for (Standard_Integer anArgIt = 2; anArgIt < theArgsNb; ++anArgIt)
3091     {
3092       TCollection_AsciiString anArg (theArgv [anArgIt]);
3093
3094       anArg.UpperCase();
3095       if (anArg.Value (1) == '-' && !anArg.IsRealValue())
3096       {
3097         aParseKey = anArg;
3098         aParseKey.Remove (1);
3099         aParseKey.UpperCase();
3100         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
3101         continue;
3102       }
3103
3104       if (aParseKey.IsEmpty())
3105       {
3106         continue;
3107       }
3108
3109       aMapOfArgs(aParseKey)->Append (anArg);
3110     }
3111   }
3112   else if (aCommandName == "vtexscale"
3113         || aCommandName == "vtexorigin"
3114         || aCommandName == "vtexrepeat")
3115   {
3116     // scan for parameters of vtexscale, vtexorigin, vtexrepeat commands
3117     // equal to -scale, -origin, -repeat options of vtexture command
3118     if (theArgsNb < 2 || theArgsNb > 4)
3119     {
3120       std::cout << theArgv[0] << ":  invalid arguments.\n";
3121       std::cout << "Type help for more information.\n";
3122       return 1;
3123     }
3124
3125     Handle(TColStd_HSequenceOfAsciiString) anArgs = new TColStd_HSequenceOfAsciiString;
3126     if (theArgsNb == 2)
3127     {
3128       anArgs->Append ("OFF");
3129     }
3130     else if (theArgsNb == 4)
3131     {
3132       anArgs->Append (TCollection_AsciiString (theArgv[2]));
3133       anArgs->Append (TCollection_AsciiString (theArgv[3]));
3134     }
3135
3136     TCollection_AsciiString anArgKey;
3137     if (aCommandName == "vtexscale")
3138     {
3139       anArgKey = "SCALE";
3140     }
3141     else if (aCommandName == "vtexorigin")
3142     {
3143       anArgKey = "ORIGIN";
3144     }
3145     else
3146     {
3147       anArgKey = "REPEAT";
3148     }
3149
3150     aMapOfArgs.Bind (anArgKey, anArgs);
3151   }
3152   else if (aCommandName == "vtexdefault")
3153   {
3154     // scan for parameters of vtexdefault command
3155     // equal to -default option of vtexture command
3156     aMapOfArgs.Bind ("DEFAULT", new TColStd_HSequenceOfAsciiString);
3157   }
3158
3159   // Check arguments for validity
3160   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
3161   for (; aMapIt.More(); aMapIt.Next())
3162   {
3163     const TCollection_AsciiString& aKey = aMapIt.Key();
3164     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
3165
3166     // -scale, -origin, -repeat: one argument "off", or two real values
3167     if ((aKey.IsEqual ("SCALE") || aKey.IsEqual ("ORIGIN") || aKey.IsEqual ("REPEAT"))
3168       && ((anArgs->Length() == 1 && anArgs->Value(1) == "OFF")
3169        || (anArgs->Length() == 2 && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue())))
3170     {
3171       continue;
3172     }
3173
3174     // -modulate: single argument "on" / "off"
3175     if (aKey.IsEqual ("MODULATE") && anArgs->Length() == 1 && (anArgs->Value(1) == "OFF" || anArgs->Value(1) == "ON"))
3176     {
3177       continue;
3178     }
3179
3180     // -default: no arguments
3181     if (aKey.IsEqual ("DEFAULT") && anArgs->IsEmpty())
3182     {
3183       continue;
3184     }
3185
3186     TCollection_AsciiString aLowerKey;
3187     aLowerKey  = "-";
3188     aLowerKey += aKey;
3189     aLowerKey.LowerCase();
3190     std::cout << theArgv[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
3191     std::cout << "Type help for more information.\n";
3192     return 1;
3193   }
3194
3195   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3196   if (anAISContext.IsNull())
3197   {
3198     std::cout << aCommandName << ":  please use 'vinit' command to initialize view.\n";
3199     return 1;
3200   }
3201
3202   Standard_Integer aPreviousMode = 0;
3203
3204   ViewerTest::CurrentView()->SetSurfaceDetail (V3d_TEX_ALL);
3205
3206   TCollection_AsciiString aShapeName (theArgv[1]);
3207   Handle(AIS_InteractiveObject) anIO;
3208
3209   const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
3210   if (aMapOfIO.IsBound2 (aShapeName))
3211   {
3212     anIO = Handle(AIS_InteractiveObject)::DownCast (aMapOfIO.Find2 (aShapeName));
3213   }
3214
3215   if (anIO.IsNull())
3216   {
3217     std::cout << aCommandName << ": shape " << aShapeName << " does not exists.\n";
3218     return 1;
3219   }
3220
3221   Handle(AIS_TexturedShape) aTexturedIO;
3222   if (anIO->IsKind (STANDARD_TYPE (AIS_TexturedShape)))
3223   {
3224     aTexturedIO = Handle(AIS_TexturedShape)::DownCast (anIO);
3225     aPreviousMode = aTexturedIO->DisplayMode();
3226   }
3227   else
3228   {
3229     aTexturedIO = new AIS_TexturedShape (DBRep::Get (theArgv[1]));
3230
3231     if (anIO->HasTransformation())
3232     {
3233       const gp_Trsf& aLocalTrsf = anIO->LocalTransformation();
3234       aTexturedIO->SetLocalTransformation (aLocalTrsf);
3235     }
3236
3237     anAISContext->Remove (anIO, Standard_False);
3238     GetMapOfAIS().UnBind1 (anIO);
3239     GetMapOfAIS().UnBind2 (aShapeName);
3240     GetMapOfAIS().Bind (aTexturedIO, aShapeName);
3241   }
3242
3243   // -------------------------------------------
3244   //  Turn texturing on/off - only for vtexture
3245   // -------------------------------------------
3246
3247   if (aCommandName == "vtexture")
3248   {
3249     TCollection_AsciiString aTextureArg (theArgsNb > 2 ? theArgv[2] : "");
3250
3251     if (aTextureArg.IsEmpty())
3252     {
3253       std::cout << aCommandName << ":  Texture mapping disabled.\n";
3254       std::cout << "To enable it, use 'vtexture NameOfShape NameOfTexture'\n\n";
3255
3256       anAISContext->SetDisplayMode (aTexturedIO, AIS_Shaded, Standard_False);
3257       if (aPreviousMode == 3)
3258       {
3259         anAISContext->RecomputePrsOnly (aTexturedIO);
3260       }
3261
3262       anAISContext->Display (aTexturedIO, Standard_True);
3263       return 0;
3264     }
3265     else if (aTextureArg.Value(1) != '-') // "-option" on place of texture argument
3266     {
3267       if (aTextureArg == "?")
3268       {
3269         TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
3270
3271         theDi << "\n Files in current directory : \n\n";
3272         theDi.Eval ("glob -nocomplain *");
3273
3274         TCollection_AsciiString aCmnd ("glob -nocomplain ");
3275         aCmnd += aTextureFolder;
3276         aCmnd += "/* ";
3277
3278         theDi << "Files in " << aTextureFolder.ToCString() << " : \n\n";
3279         theDi.Eval (aCmnd.ToCString());
3280         return 0;
3281       }
3282       else
3283       {
3284         aTexturedIO->SetTextureFileName (aTextureArg);
3285       }
3286     }
3287   }
3288
3289   // ------------------------------------
3290   //  Process other options and commands
3291   // ------------------------------------
3292
3293   Handle(TColStd_HSequenceOfAsciiString) aValues;
3294   if (aMapOfArgs.Find ("DEFAULT", aValues))
3295   {
3296     aTexturedIO->SetTextureRepeat (Standard_False);
3297     aTexturedIO->SetTextureOrigin (Standard_False);
3298     aTexturedIO->SetTextureScale  (Standard_False);
3299     aTexturedIO->EnableTextureModulate();
3300   }
3301   else
3302   {
3303     if (aMapOfArgs.Find ("SCALE", aValues))
3304     {
3305       if (aValues->Value(1) != "OFF")
3306       {
3307         aTexturedIO->SetTextureScale (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3308       }
3309       else
3310       {
3311         aTexturedIO->SetTextureScale (Standard_False);
3312       }
3313     }
3314
3315     if (aMapOfArgs.Find ("ORIGIN", aValues))
3316     {
3317       if (aValues->Value(1) != "OFF")
3318       {
3319         aTexturedIO->SetTextureOrigin (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3320       }
3321       else
3322       {
3323         aTexturedIO->SetTextureOrigin (Standard_False);
3324       }
3325     }
3326
3327     if (aMapOfArgs.Find ("REPEAT", aValues))
3328     {
3329       if (aValues->Value(1) != "OFF")
3330       {
3331         aTexturedIO->SetTextureRepeat (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3332       }
3333       else
3334       {
3335         aTexturedIO->SetTextureRepeat (Standard_False);
3336       }
3337     }
3338
3339     if (aMapOfArgs.Find ("MODULATE", aValues))
3340     {
3341       if (aValues->Value(1) == "ON")
3342       {
3343         aTexturedIO->EnableTextureModulate();
3344       }
3345       else
3346       {
3347         aTexturedIO->DisableTextureModulate();
3348       }
3349     }
3350   }
3351
3352   if (aTexturedIO->DisplayMode() == 3 || aPreviousMode == 3)
3353   {
3354     anAISContext->RecomputePrsOnly (aTexturedIO);
3355   }
3356   else
3357   {
3358     anAISContext->SetDisplayMode (aTexturedIO, 3, Standard_False);
3359     anAISContext->Display (aTexturedIO, Standard_True);
3360     anAISContext->Update (aTexturedIO,Standard_True);
3361   }
3362
3363   return 0;
3364 }
3365
3366 //! Auxiliary method to parse transformation persistence flags
3367 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
3368                                            Standard_Integer&              theFlags)
3369 {
3370   if (theFlagString == "pan")
3371   {
3372     theFlags |= Graphic3d_TMF_PanPers;
3373   }
3374   else if (theFlagString == "zoom")
3375   {
3376     theFlags |= Graphic3d_TMF_ZoomPers;
3377   }
3378   else if (theFlagString == "rotate")
3379   {
3380     theFlags |= Graphic3d_TMF_RotatePers;
3381   }
3382   else if (theFlagString == "trihedron")
3383   {
3384     theFlags = Graphic3d_TMF_TriedronPers;
3385   }
3386   else if (theFlagString == "full")
3387   {
3388     theFlags = Graphic3d_TMF_FullPers;
3389   }
3390   else if (theFlagString == "none")
3391   {
3392     theFlags = Graphic3d_TMF_None;
3393   }
3394   else
3395   {
3396     return Standard_False;
3397   }
3398
3399   return Standard_True;
3400 }
3401
3402 //==============================================================================
3403 //function : VDisplay2
3404 //author   : ege
3405 //purpose  : Display an object from its name
3406 //==============================================================================
3407 static int VDisplay2 (Draw_Interpretor& theDI,
3408                       Standard_Integer  theArgNb,
3409                       const char**      theArgVec)
3410 {
3411   if (theArgNb < 2)
3412   {
3413     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
3414     return 1;
3415   }
3416
3417   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3418   if (aCtx.IsNull())
3419   {
3420     ViewerTest::ViewerInit();
3421     aCtx = ViewerTest::GetAISContext();
3422   }
3423
3424   // Parse input arguments
3425   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3426   Standard_Integer   isMutable      = -1;
3427   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
3428   Standard_Boolean   toDisplayLocal = Standard_False;
3429   Standard_Boolean   toReDisplay    = Standard_False;
3430   Standard_Integer   isSelectable   = -1;
3431   Standard_Integer   anObjDispMode  = -2;
3432   Standard_Integer   anObjHighMode  = -2;
3433   Standard_Boolean   toSetTrsfPers  = Standard_False;
3434   Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
3435   gp_Pnt aTPPosition;
3436   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
3437   AIS_DisplayStatus aDispStatus = AIS_DS_None;
3438   Standard_Integer toDisplayInView = Standard_False;
3439   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3440   {
3441     const TCollection_AsciiString aName     = theArgVec[anArgIter];
3442     TCollection_AsciiString       aNameCase = aName;
3443     aNameCase.LowerCase();
3444     if (anUpdateTool.parseRedrawMode (aName))
3445     {
3446       continue;
3447     }
3448     else if (aNameCase == "-mutable")
3449     {
3450       isMutable = 1;
3451     }
3452     else if (aNameCase == "-neutral")
3453     {
3454       aDispStatus = AIS_DS_Displayed;
3455     }
3456     else if (aNameCase == "-immediate"
3457           || aNameCase == "-top")
3458     {
3459       aZLayer = Graphic3d_ZLayerId_Top;
3460     }
3461     else if (aNameCase == "-topmost")
3462     {
3463       aZLayer = Graphic3d_ZLayerId_Topmost;
3464     }
3465     else if (aNameCase == "-osd"
3466           || aNameCase == "-toposd"
3467           || aNameCase == "-overlay")
3468     {
3469       aZLayer = Graphic3d_ZLayerId_TopOSD;
3470     }
3471     else if (aNameCase == "-botosd"
3472           || aNameCase == "-underlay")
3473     {
3474       aZLayer = Graphic3d_ZLayerId_BotOSD;
3475     }
3476     else if (aNameCase == "-select"
3477           || aNameCase == "-selectable")
3478     {
3479       isSelectable = 1;
3480     }
3481     else if (aNameCase == "-noselect"
3482           || aNameCase == "-noselection")
3483     {
3484       isSelectable = 0;
3485     }
3486     else if (aNameCase == "-dispmode"
3487           || aNameCase == "-displaymode")
3488     {
3489       if (++anArgIter >= theArgNb)
3490       {
3491         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3492         return 1;
3493       }
3494
3495       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
3496     }
3497     else if (aNameCase == "-highmode"
3498           || aNameCase == "-highlightmode")
3499     {
3500       if (++anArgIter >= theArgNb)
3501       {
3502         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3503         return 1;
3504       }
3505
3506       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
3507     }
3508     else if (aNameCase == "-3d")
3509     {
3510       toSetTrsfPers  = Standard_True;
3511       aTrsfPersFlags = Graphic3d_TMF_None;
3512     }
3513     else if (aNameCase == "-2d")
3514     {
3515       toSetTrsfPers  = Standard_True;
3516       aTrsfPersFlags = Graphic3d_TMF_2d;
3517     }
3518     else if (aNameCase == "-2dtopdown")
3519     {
3520       toSetTrsfPers  = Standard_True;
3521       aTrsfPersFlags = Graphic3d_TMF_2d | Graphic3d_TMF_2d_IsTopDown;
3522     }
3523     else if (aNameCase == "-trsfpers"
3524           || aNameCase == "-pers")
3525     {
3526       if (++anArgIter >= theArgNb)
3527       {
3528         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3529         return 1;
3530       }
3531
3532       toSetTrsfPers  = Standard_True;
3533       aTrsfPersFlags = Graphic3d_TMF_None;
3534       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
3535       aPersFlags.LowerCase();
3536       for (Standard_Integer aParserPos = aPersFlags.Search ("|");; aParserPos = aPersFlags.Search ("|"))
3537       {
3538         if (aParserPos == -1)
3539         {
3540           if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
3541           {
3542             std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
3543             return 1;
3544           }
3545           break;
3546         }
3547
3548         TCollection_AsciiString anOtherFlags = aPersFlags.Split (aParserPos - 1);
3549         if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
3550         {
3551           std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
3552           return 1;
3553         }
3554         aPersFlags = anOtherFlags;
3555       }
3556     }
3557     else if (aNameCase == "-trsfperspos"
3558           || aNameCase == "-perspos")
3559     {
3560       if (anArgIter + 2 >= theArgNb)
3561       {
3562         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3563         return 1;
3564       }
3565
3566       TCollection_AsciiString aX (theArgVec[++anArgIter]);
3567       TCollection_AsciiString aY (theArgVec[++anArgIter]);
3568       TCollection_AsciiString aZ = "0";
3569       if (!aX.IsIntegerValue()
3570        || !aY.IsIntegerValue())
3571       {
3572         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3573         return 1;
3574       }
3575       if (anArgIter + 1 < theArgNb)
3576       {
3577         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
3578         if (aTemp.IsIntegerValue())
3579         {
3580           aZ = aTemp;
3581           ++anArgIter;
3582         }
3583       }
3584       aTPPosition.SetCoord (aX.IntegerValue(), aY.IntegerValue(), aZ.IntegerValue());
3585     }
3586     else if (aNameCase == "-layer")
3587     {
3588       if (++anArgIter >= theArgNb)
3589       {
3590         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3591         return 1;
3592       }
3593
3594       TCollection_AsciiString aValue (theArgVec[anArgIter]);
3595       if (!aValue.IsIntegerValue())
3596       {
3597         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3598         return 1;
3599       }
3600
3601       aZLayer = aValue.IntegerValue();
3602     }
3603     else if (aNameCase == "-view"
3604           || aNameCase == "-inview")
3605     {
3606       toDisplayInView = Standard_True;
3607     }
3608     else if (aNameCase == "-local")
3609     {
3610       aDispStatus = AIS_DS_Temporary;
3611       toDisplayLocal = Standard_True;
3612     }
3613     else if (aNameCase == "-redisplay")
3614     {
3615       toReDisplay = Standard_True;
3616     }
3617     else
3618     {
3619       aNamesOfDisplayIO.Append (aName);
3620     }
3621   }
3622
3623   if (aNamesOfDisplayIO.IsEmpty())
3624   {
3625     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
3626     return 1;
3627   }
3628
3629   // Prepare context for display
3630   if (toDisplayLocal && !aCtx->HasOpenedContext())
3631   {
3632     aCtx->OpenLocalContext (Standard_False);
3633   }
3634   else if (!toDisplayLocal && aCtx->HasOpenedContext())
3635   {
3636     aCtx->CloseAllContexts (Standard_False);
3637   }
3638
3639   // Display interactive objects
3640   for (Standard_Integer anIter = 1; anIter <= aNamesOfDisplayIO.Length(); ++anIter)
3641   {
3642     const TCollection_AsciiString& aName = aNamesOfDisplayIO.Value(anIter);
3643
3644     if (!GetMapOfAIS().IsBound2 (aName))
3645     {
3646       // create the AIS_Shape from a name
3647       const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
3648       if (!aShape.IsNull())
3649       {
3650         if (isMutable != -1)
3651         {
3652           aShape->SetMutable (isMutable == 1);
3653         }
3654         if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
3655         {
3656           aShape->SetZLayer (aZLayer);
3657         }
3658         if (toSetTrsfPers)
3659         {
3660           aShape->SetTransformPersistence (aTrsfPersFlags, aTPPosition);
3661         }
3662         if (anObjDispMode != -2)
3663         {
3664           aShape->SetDisplayMode (anObjDispMode);
3665         }
3666         if (anObjHighMode != -2)
3667         {
3668           aShape->SetHilightMode (anObjHighMode);
3669         }
3670         if (!toDisplayLocal)
3671           GetMapOfAIS().Bind (aShape, aName);
3672
3673         Standard_Integer aDispMode = aShape->HasDisplayMode()
3674                                    ? aShape->DisplayMode()
3675                                    : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
3676                                     ? aCtx->DisplayMode()
3677                                     : 0);
3678         Standard_Integer aSelMode = -1;
3679         if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
3680         {
3681           aSelMode = aShape->GlobalSelectionMode();
3682         }
3683
3684         aCtx->Display (aShape, aDispMode, aSelMode,
3685                        Standard_False, aShape->AcceptShapeDecomposition(),
3686                        aDispStatus);
3687         if (toDisplayInView)
3688         {
3689           for (aCtx->CurrentViewer()->InitDefinedViews(); aCtx->CurrentViewer()->MoreDefinedViews(); aCtx->CurrentViewer()->NextDefinedViews())
3690           {
3691             aCtx->SetViewAffinity (aShape, aCtx->CurrentViewer()->DefinedView(), Standard_False);
3692           }
3693           aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
3694         }
3695       }
3696       else
3697       {
3698         std::cerr << "Error: object with name '" << aName << "' does not exist!\n";
3699       }
3700       continue;
3701     }
3702
3703     Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
3704     if (isMutable != -1)
3705     {
3706       aShape->SetMutable (isMutable == 1);
3707     }
3708     if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
3709     {
3710       aShape->SetZLayer (aZLayer);
3711     }
3712     if (toSetTrsfPers)
3713     {
3714       aShape->SetTransformPersistence (aTrsfPersFlags, aTPPosition);
3715     }
3716     if (anObjDispMode != -2)
3717     {
3718       aShape->SetDisplayMode (anObjDispMode);
3719     }
3720     if (anObjHighMode != -2)
3721     {
3722       aShape->SetHilightMode (anObjHighMode);
3723     }
3724     Standard_Integer aDispMode = aShape->HasDisplayMode()
3725                                 ? aShape->DisplayMode()
3726                                 : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
3727                                 ? aCtx->DisplayMode()
3728                                 : 0);
3729     Standard_Integer aSelMode = -1;
3730     if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
3731     {
3732       aSelMode = aShape->GlobalSelectionMode();
3733     }
3734
3735     if (aShape->Type() == AIS_KOI_Datum)
3736     {
3737       aCtx->Display (aShape, Standard_False);
3738     }
3739     else
3740     {
3741       theDI << "Display " << aName.ToCString() << "\n";
3742
3743       // update the Shape in the AIS_Shape
3744       TopoDS_Shape      aNewShape = GetShapeFromName (aName.ToCString());
3745       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
3746       if (!aShapePrs.IsNull())
3747       {
3748         if (!aShapePrs->Shape().IsEqual (aNewShape))
3749         {
3750           toReDisplay = Standard_True;
3751         }
3752         aShapePrs->Set (aNewShape);
3753       }
3754       if (toReDisplay)
3755       {
3756         aCtx->Redisplay (aShape, Standard_False);
3757       }
3758
3759       if (aSelMode == -1)
3760       {
3761         aCtx->Erase (aShape);
3762       }
3763       aCtx->Display (aShape, aDispMode, aSelMode,
3764                      Standard_False, aShape->AcceptShapeDecomposition(),
3765                      aDispStatus);
3766       if (toDisplayInView)
3767       {
3768         aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
3769       }
3770     }
3771   }
3772
3773   return 0;
3774 }
3775
3776 //===============================================================================================
3777 //function : VUpdate
3778 //purpose  :
3779 //===============================================================================================
3780 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
3781 {
3782   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3783   if (aContextAIS.IsNull())
3784   {
3785     std::cout << theArgVec[0] << "AIS context is not available.\n";
3786     return 1;
3787   }
3788
3789   if (theArgsNb < 2)
3790   {
3791     std::cout << theArgVec[0] << ": insufficient arguments. Type help for more information.\n";
3792     return 1;
3793   }
3794
3795   const ViewerTest_DoubleMapOfInteractiveAndName& anAISMap = GetMapOfAIS();
3796
3797   AIS_ListOfInteractive aListOfIO;
3798
3799   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
3800   {
3801     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
3802
3803     Handle(AIS_InteractiveObject) anAISObj;
3804     if (anAISMap.IsBound2 (aName))
3805     {
3806       anAISObj = Handle(AIS_InteractiveObject)::DownCast (anAISMap.Find2 (aName));
3807     }
3808
3809     if (anAISObj.IsNull())
3810     {
3811       std::cout << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".\n";
3812       return 1;
3813     }
3814
3815     aListOfIO.Append (anAISObj);
3816   }
3817
3818   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
3819   for (; anIOIt.More(); anIOIt.Next())
3820   {
3821     aContextAIS->Update (anIOIt.Value(), Standard_False);
3822   }
3823
3824   aContextAIS->UpdateCurrentViewer();
3825
3826   return 0;
3827 }
3828
3829 //==============================================================================
3830 //function : VPerf
3831 //purpose  : Test the annimation of an object along a
3832 //           predifined trajectory
3833 //Draw arg : vperf ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)
3834 //==============================================================================
3835
3836 static int VPerf(Draw_Interpretor& di, Standard_Integer , const char** argv) {
3837
3838   OSD_Timer myTimer;
3839   if (TheAISContext()->HasOpenedContext())
3840     TheAISContext()->CloseLocalContext();
3841
3842   Standard_Real Step=4*M_PI/180;
3843   Standard_Real Angle=0;
3844
3845   Handle(AIS_InteractiveObject) aIO;
3846   if (GetMapOfAIS().IsBound2(argv[1]))
3847     aIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
3848   if (aIO.IsNull())
3849     return 1;
3850
3851   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aIO);
3852
3853   myTimer.Start();
3854
3855   if (Draw::Atoi(argv[3])==1 ) {
3856     di<<" Primitives sensibles OFF\n";
3857     TheAISContext()->Deactivate(aIO);
3858   }
3859   else {
3860     di<<" Primitives sensibles ON\n";
3861   }
3862   // Movement par transformation
3863   if(Draw::Atoi(argv[2]) ==1) {
3864     di<<" Calcul par Transformation\n";
3865     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3866
3867       Angle=Step*myAngle;
3868       gp_Trsf myTransfo;
3869       myTransfo.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ) ,Angle );
3870       TheAISContext()->SetLocation(aShape,myTransfo);
3871       TheAISContext() ->UpdateCurrentViewer();
3872
3873     }
3874   }
3875   else {
3876     di<<" Calcul par Locations\n";
3877     gp_Trsf myAngleTrsf;
3878     myAngleTrsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ), Step  );
3879     TopLoc_Location myDeltaAngle (myAngleTrsf);
3880     TopLoc_Location myTrueLoc;
3881
3882     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3883
3884       Angle=Step*myAngle;
3885       myTrueLoc=myTrueLoc*myDeltaAngle;
3886       TheAISContext()->SetLocation(aShape,myTrueLoc );
3887       TheAISContext() ->UpdateCurrentViewer();
3888     }
3889   }
3890   if (Draw::Atoi(argv[3])==1 ){
3891     // On reactive la selection des primitives sensibles
3892     TheAISContext()->Activate(aIO,0);
3893   }
3894   a3DView() -> Redraw();
3895   myTimer.Stop();
3896   di<<" Temps ecoule \n";
3897   myTimer.Show();
3898   return 0;
3899 }
3900
3901
3902 //==================================================================================
3903 // Function : VAnimation
3904 //==================================================================================
3905 static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
3906   if (argc != 5) {
3907     di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile\n";
3908     return 1;
3909   }
3910
3911   Standard_Real thread = 4;
3912   Standard_Real angleA=0;
3913   Standard_Real angleB;
3914   Standard_Real X;
3915   gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
3916
3917   BRep_Builder B;
3918   TopoDS_Shape CrankArm;
3919   TopoDS_Shape CylinderHead;
3920   TopoDS_Shape Propeller;
3921   TopoDS_Shape EngineBlock;
3922
3923   //BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
3924   //BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
3925   //BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
3926   //BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
3927   BRepTools::Read(CrankArm,argv[1],B);
3928   BRepTools::Read(CylinderHead,argv[2],B);
3929   BRepTools::Read(Propeller,argv[3],B);
3930   BRepTools::Read(EngineBlock,argv[4],B);
3931
3932   if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure.\n";}
3933
3934
3935   OSD_Timer myTimer;
3936   myTimer.Start();
3937
3938   Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
3939   Handle(AIS_Shape) myAisEngineBlock  = new AIS_Shape (EngineBlock);
3940   Handle(AIS_Shape) myAisCrankArm     = new AIS_Shape (CrankArm);
3941   Handle(AIS_Shape) myAisPropeller    = new AIS_Shape (Propeller);
3942
3943   GetMapOfAIS().Bind(myAisCylinderHead,"a");
3944   GetMapOfAIS().Bind(myAisEngineBlock,"b");
3945   GetMapOfAIS().Bind(myAisCrankArm,"c");
3946   GetMapOfAIS().Bind(myAisPropeller,"d");
3947
3948   myAisCylinderHead->SetMutable (Standard_True);
3949   myAisEngineBlock ->SetMutable (Standard_True);
3950   myAisCrankArm    ->SetMutable (Standard_True);
3951   myAisPropeller   ->SetMutable (Standard_True);
3952
3953   TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
3954   TheAISContext()->SetColor (myAisEngineBlock,  Quantity_NOC_RED);
3955   TheAISContext()->SetColor (myAisPropeller,    Quantity_NOC_GREEN);
3956
3957   TheAISContext()->Display (myAisCylinderHead, Standard_False);
3958   TheAISContext()->Display (myAisEngineBlock,  Standard_False);
3959   TheAISContext()->Display (myAisCrankArm,     Standard_False);
3960   TheAISContext()->Display (myAisPropeller,    Standard_False);
3961
3962   TheAISContext()->Deactivate(myAisCylinderHead);
3963   TheAISContext()->Deactivate(myAisEngineBlock );
3964   TheAISContext()->Deactivate(myAisCrankArm    );
3965   TheAISContext()->Deactivate(myAisPropeller   );
3966
3967   // Boucle de mouvement
3968   for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
3969
3970     angleA = thread*myAngle*M_PI/180;
3971     X = Sin(angleA)*3/8;
3972     angleB = atan(X / Sqrt(-X * X + 1));
3973     Standard_Real decal(25*0.6);
3974
3975
3976     //Build a transformation on the display
3977     gp_Trsf aPropellerTrsf;
3978     aPropellerTrsf.SetRotation(Ax1,angleA);
3979     TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
3980
3981     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));
3982     gp_Trsf aCrankArmTrsf;
3983     aCrankArmTrsf.SetTransformation(   base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
3984     TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
3985
3986     TheAISContext()->UpdateCurrentViewer();
3987   }
3988
3989   TopoDS_Shape myNewCrankArm  =myAisCrankArm ->Shape().Located( myAisCrankArm ->Transformation() );
3990   TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Transformation() );
3991
3992   myAisCrankArm ->ResetTransformation();
3993   myAisPropeller->ResetTransformation();
3994
3995   myAisCrankArm  -> Set(myNewCrankArm );
3996   myAisPropeller -> Set(myNewPropeller);
3997
3998   TheAISContext()->Activate(myAisCylinderHead,0);
3999   TheAISContext()->Activate(myAisEngineBlock,0 );
4000   TheAISContext()->Activate(myAisCrankArm ,0   );
4001   TheAISContext()->Activate(myAisPropeller ,0  );
4002
4003   myTimer.Stop();
4004   myTimer.Show();
4005   myTimer.Start();
4006
4007   TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
4008   TheAISContext()->Redisplay(myAisPropeller,Standard_False);
4009
4010   TheAISContext()->UpdateCurrentViewer();
4011   a3DView()->Redraw();
4012
4013   myTimer.Stop();
4014   myTimer.Show();
4015
4016   return 0;
4017
4018 }
4019
4020 //==============================================================================
4021 //function : VShading
4022 //purpose  : Sharpen or roughten the quality of the shading
4023 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
4024 //==============================================================================
4025 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
4026 {
4027   Standard_Real    myDevCoef;
4028   Handle(AIS_InteractiveObject) TheAisIO;
4029
4030   // Verifications
4031   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
4032
4033   if (TheAISContext()->HasOpenedContext())
4034     TheAISContext()->CloseLocalContext();
4035
4036   if (argc < 3) {
4037     myDevCoef  = 0.0008;
4038   } else {
4039     myDevCoef  =Draw::Atof(argv[2]);
4040   }
4041
4042   TCollection_AsciiString name=argv[1];
4043   if (GetMapOfAIS().IsBound2(name ))
4044     TheAisIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
4045   if (TheAisIO.IsNull())
4046     TheAisIO=GetAISShapeFromName((const char *)name.ToCString());
4047
4048   if (HaveToSet)
4049     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
4050   else
4051     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
4052
4053   TheAISContext()->Redisplay(TheAisIO);
4054   return 0;
4055 }
4056 //==============================================================================
4057 //function : HaveMode
4058 //use      : VActivatedModes
4059 //==============================================================================
4060 #include <TColStd_ListIteratorOfListOfInteger.hxx>
4061
4062 Standard_Boolean  HaveMode(const Handle(AIS_InteractiveObject)& TheAisIO,const Standard_Integer mode  )
4063 {
4064   TColStd_ListOfInteger List;
4065   TheAISContext()->ActivatedModes (TheAisIO,List);
4066   TColStd_ListIteratorOfListOfInteger it;
4067   Standard_Boolean Found=Standard_False;
4068   for (it.Initialize(List); it.More()&&!Found; it.Next() ){
4069     if (it.Value()==mode ) Found=Standard_True;
4070   }
4071   return Found;
4072 }
4073
4074
4075
4076 //==============================================================================
4077 //function : VActivatedMode
4078 //author   : ege
4079 //purpose  : permet d'attribuer a chacune des shapes un mode d'activation
4080 //           (edges,vertex...)qui lui est propre et le mode de selection standard.
4081 //           La fonction s'applique aux shapes selectionnees(current ou selected dans le viewer)
4082 //             Dans le cas ou on veut psser la shape en argument, la fonction n'autorise
4083 //           qu'un nom et qu'un mode.
4084 //Draw arg : vsetam  [ShapeName] mode(0,1,2,3,4,5,6,7)
4085 //==============================================================================
4086 #include <AIS_ListIteratorOfListOfInteractive.hxx>
4087
4088 static int VActivatedMode (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4089
4090 {
4091   Standard_Boolean ThereIsName = Standard_False ;
4092
4093   if(!a3DView().IsNull()){
4094
4095     const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetam") == 0);
4096     // verification des arguments
4097     if (HaveToSet) {
4098       if (argc<2||argc>3) { di<<" Syntaxe error\n";return 1;}
4099       ThereIsName = (argc == 3);
4100     }
4101     else {
4102       // vunsetam
4103       if (argc>1) {di<<" Syntaxe error\n";return 1;}
4104       else {
4105         di<<" R.A.Z de tous les modes de selecion\n";
4106         di<<" Fermeture du Context local\n";
4107         if (TheAISContext()->HasOpenedContext())
4108           TheAISContext()->CloseLocalContext();
4109       }
4110     }
4111
4112     // IL n'y a aps de nom de shape passe en argument
4113     if (HaveToSet && !ThereIsName){
4114       Standard_Integer aMode=Draw::Atoi(argv [1]);
4115
4116       const char *cmode="???";
4117       switch (aMode) {
4118       case 0: cmode = "Shape"; break;
4119       case 1: cmode = "Vertex"; break;
4120       case 2: cmode = "Edge"; break;
4121       case 3: cmode = "Wire"; break;
4122       case 4: cmode = "Face"; break;
4123       case 5: cmode = "Shell"; break;
4124       case 6: cmode = "Solid"; break;
4125       case 7: cmode = "Compound"; break;
4126       }
4127
4128       if( !TheAISContext()->HasOpenedContext() ) {
4129         // il n'y a pas de Context local d'ouvert
4130         // on en ouvre un et on charge toutes les shapes displayees
4131         // on load tous les objets displayees et on Activate les objets de la liste
4132         AIS_ListOfInteractive ListOfIO;
4133         // on sauve dans une AISListOfInteractive tous les objets currents
4134         if (TheAISContext()->NbSelected()>0 ){
4135           TheAISContext()->UnhilightSelected(Standard_False);
4136
4137           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
4138             ListOfIO.Append(TheAISContext()->SelectedInteractive() );
4139           }
4140         }
4141
4142         TheAISContext()->OpenLocalContext(Standard_False);
4143         ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4144           it (GetMapOfAIS());
4145         while(it.More()){
4146           Handle(AIS_InteractiveObject) aIO =
4147             Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4148           if (!aIO.IsNull())
4149             TheAISContext()->Load(aIO,0,Standard_False);
4150           it.Next();
4151         }
4152         // traitement des objets qui etaient currents dans le Contexte global
4153         if (!ListOfIO.IsEmpty() ) {
4154           // il y avait des objets currents
4155           AIS_ListIteratorOfListOfInteractive iter;
4156           for (iter.Initialize(ListOfIO); iter.More() ; iter.Next() ) {
4157             Handle(AIS_InteractiveObject) aIO=iter.Value();
4158             TheAISContext()->Activate(aIO,aMode);
4159             di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString()  <<"\n";
4160           }
4161         }
4162         else {
4163           // On applique le mode a tous les objets displayes
4164           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4165             it2 (GetMapOfAIS());
4166           while(it2.More()){
4167             Handle(AIS_InteractiveObject) aIO =
4168               Handle(AIS_InteractiveObject)::DownCast(it2.Key1());
4169             if (!aIO.IsNull()) {
4170               di<<" Mode: "<<cmode<<" ON pour "<<it2.Key2().ToCString() <<"\n";
4171               TheAISContext()->Activate(aIO,aMode);
4172             }
4173             it2.Next();
4174           }
4175         }
4176
4177       }
4178
4179       else {
4180         // un Context local est deja ouvert
4181         // Traitement des objets du Context local
4182         if (TheAISContext()->NbSelected()>0 ){
4183           TheAISContext()->UnhilightSelected(Standard_False);
4184           // il y a des objets selected,on les parcourt
4185           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
4186             Handle(AIS_InteractiveObject) aIO=TheAISContext()->SelectedInteractive();
4187
4188
4189             if (HaveMode(aIO,aMode) ) {
4190               di<<" Mode: "<<cmode<<" OFF pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4191               TheAISContext()->Deactivate(aIO,aMode);
4192             }
4193             else{
4194               di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4195               TheAISContext()->Activate(aIO,aMode);
4196             }
4197
4198           }
4199         }
4200         else{
4201           // il n'y a pas d'objets selected
4202           // tous les objets diplayes sont traites
4203           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4204             it (GetMapOfAIS());
4205           while(it.More()){
4206             Handle(AIS_InteractiveObject) aIO =
4207               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4208             if (!aIO.IsNull()) {
4209               if (HaveMode(aIO,aMode) ) {
4210                 di<<" Mode: "<<cmode<<" OFF pour "
4211                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4212                 TheAISContext()->Deactivate(aIO,aMode);
4213               }
4214               else{
4215                 di<<" Mode: "<<cmode<<" ON pour"
4216                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4217                 TheAISContext()->Activate(aIO,aMode);
4218               }
4219             }
4220             it.Next();
4221           }
4222         }
4223       }
4224     }
4225     else if (HaveToSet && ThereIsName){
4226       Standard_Integer aMode=Draw::Atoi(argv [2]);
4227       Handle(AIS_InteractiveObject) aIO =
4228         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
4229
4230       if (!aIO.IsNull()) {
4231         const char *cmode="???";
4232
4233         switch (aMode) {
4234         case 0: cmode = "Shape"; break;
4235         case 1: cmode = "Vertex"; break;
4236         case 2: cmode = "Edge"; break;
4237         case 3: cmode = "Wire"; break;
4238         case 4: cmode = "Face"; break;
4239         case 5: cmode = "Shell"; break;
4240         case 6: cmode = "Solid"; break;
4241         case 7: cmode = "Compound"; break;
4242         }
4243
4244         if( !TheAISContext()->HasOpenedContext() ) {
4245           TheAISContext()->OpenLocalContext(Standard_False);
4246           // On charge tous les objets de la map
4247           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it (GetMapOfAIS());
4248           while(it.More()){
4249             Handle(AIS_InteractiveObject) aShape=
4250               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4251             if (!aShape.IsNull())
4252               TheAISContext()->Load(aShape,0,Standard_False);
4253             it.Next();
4254           }
4255           TheAISContext()->Activate(aIO,aMode);
4256           di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
4257         }
4258
4259         else {
4260           // un Context local est deja ouvert
4261           if (HaveMode(aIO,aMode) ) {
4262             di<<" Mode: "<<cmode<<" OFF pour "<<argv[1]<<"\n";
4263             TheAISContext()->Deactivate(aIO,aMode);
4264           }
4265           else{
4266             di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
4267             TheAISContext()->Activate(aIO,aMode);
4268           }
4269         }
4270       }
4271     }
4272   }
4273   return 0;
4274 }
4275
4276 //! Auxiliary method to print Interactive Object information
4277 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
4278                      const Handle(Standard_Transient)&                     theObject,
4279                      Draw_Interpretor&                                     theDI)
4280 {
4281   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theObject);
4282   if (anObj.IsNull())
4283   {
4284     theDI << theObject->DynamicType()->Name() << " is not AIS presentation\n";
4285     return;
4286   }
4287
4288   theDI << (TheAISContext()->IsDisplayed  (anObj) ? "Displayed"  : "Hidden   ")
4289         << (TheAISContext()->IsSelected   (anObj) ? " Selected" : "         ")
4290         << (theDetected.Contains (anObj)          ? " Detected" : "         ")
4291         << " Type: ";
4292   if (anObj->Type() == AIS_KOI_Datum)
4293   {
4294     // AIS_Datum
4295     if      (anObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
4296     else if (anObj->Signature() == 2) { theDI << " AIS_Axis"; }
4297     else if (anObj->Signature() == 6) { theDI << " AIS_Circle"; }
4298     else if (anObj->Signature() == 5) { theDI << " AIS_Line"; }
4299     else if (anObj->Signature() == 7) { theDI << " AIS_Plane"; }
4300     else if (anObj->Signature() == 1) { theDI << " AIS_Point"; }
4301     else if (anObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
4302   }
4303   // AIS_Shape
4304   else if (anObj->Type()      == AIS_KOI_Shape
4305         && anObj->Signature() == 0)
4306   {
4307     theDI << " AIS_Shape";
4308   }
4309   else if (anObj->Type() == AIS_KOI_Relation)
4310   {
4311     // AIS_Dimention and AIS_Relation
4312     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (anObj);
4313     switch (aRelation->KindOfDimension())
4314     {
4315       case AIS_KOD_PLANEANGLE:     theDI << " AIS_AngleDimension"; break;
4316       case AIS_KOD_LENGTH:         theDI << " AIS_Chamf2/3dDimension/AIS_LengthDimension"; break;
4317       case AIS_KOD_DIAMETER:       theDI << " AIS_DiameterDimension"; break;
4318       case AIS_KOD_ELLIPSERADIUS:  theDI << " AIS_EllipseRadiusDimension"; break;
4319       //case AIS_KOD_FILLETRADIUS:   theDI << " AIS_FilletRadiusDimension "; break;
4320       case AIS_KOD_OFFSET:         theDI << " AIS_OffsetDimension"; break;
4321       case AIS_KOD_RADIUS:         theDI << " AIS_RadiusDimension"; break;
4322       default:                     theDI << " UNKNOWN dimension"; break;
4323     }
4324   }
4325   else
4326   {
4327     theDI << " UserPrs";
4328   }
4329   theDI << " (" << theObject->DynamicType()->Name() << ")";
4330 }
4331
4332 //! Print information about locally selected sub-shapes
4333 template <typename T>
4334 static void printLocalSelectionInfo (const T& theContext, Draw_Interpretor& theDI)
4335 {
4336   const Standard_Boolean isGlobalCtx = (theContext->DynamicType() == STANDARD_TYPE(AIS_InteractiveContext));
4337   TCollection_AsciiString aPrevName;
4338   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
4339   {
4340     const Handle(AIS_Shape) aShapeIO = Handle(AIS_Shape)::DownCast (theContext->SelectedInteractive());
4341     const Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
4342     if (aShapeIO.IsNull() || anOwner.IsNull())
4343       continue;
4344     if (isGlobalCtx)
4345     {
4346       if (anOwner == aShapeIO->GlobalSelOwner())
4347         continue;
4348     }
4349     const TopoDS_Shape      aSubShape = theContext->SelectedShape();
4350     if (aSubShape.IsNull()
4351       || aShapeIO.IsNull()
4352       || !GetMapOfAIS().IsBound1 (aShapeIO))
4353     {
4354       continue;
4355     }
4356
4357     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
4358     TopTools_MapOfShape aFilter;
4359     Standard_Integer    aNumber = 0;
4360     const TopoDS_Shape  aShape  = aShapeIO->Shape();
4361     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
4362          anIter.More(); anIter.Next())
4363     {
4364       if (!aFilter.Add (anIter.Current()))
4365       {
4366         continue; // filter duplicates
4367       }
4368
4369       ++aNumber;
4370       if (!anIter.Current().IsSame (aSubShape))
4371       {
4372         continue;
4373       }
4374
4375       Standard_CString aShapeName = NULL;
4376       switch (aSubShape.ShapeType())
4377       {
4378         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
4379         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
4380         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
4381         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
4382         case TopAbs_FACE:      aShapeName = "     Face"; break;
4383         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
4384         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
4385         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
4386         default:
4387         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
4388       }
4389
4390       if (aParentName != aPrevName)
4391       {
4392         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
4393         aPrevName = aParentName;
4394       }
4395       theDI << "  " << aShapeName << " #" << aNumber << "\n";
4396       break;
4397     }
4398   }
4399 }
4400
4401 //==============================================================================
4402 //function : VState
4403 //purpose  :
4404 //==============================================================================
4405 static Standard_Integer VState (Draw_Interpretor& theDI,
4406                                 Standard_Integer  theArgNb,
4407                                 Standard_CString* theArgVec)
4408 {
4409   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
4410   if (aCtx.IsNull())
4411   {
4412     std::cerr << "Error: No opened viewer!\n";
4413     return 1;
4414   }
4415
4416   Standard_Boolean toPrintEntities = Standard_False;
4417   Standard_Boolean toCheckSelected = Standard_False;
4418
4419   for (Standard_Integer anArgIdx = 1; anArgIdx < theArgNb; ++anArgIdx)
4420   {
4421     TCollection_AsciiString anOption (theArgVec[anArgIdx]);
4422     anOption.LowerCase();
4423     if (anOption == "-detectedentities"
4424       || anOption == "-entities")
4425     {
4426       toPrintEntities = Standard_True;
4427     }
4428     else if (anOption == "-hasselected")
4429     {
4430       toCheckSelected = Standard_True;
4431     }
4432   }
4433
4434   if (toCheckSelected)
4435   {
4436     aCtx->InitSelected();
4437     TCollection_AsciiString hasSelected (static_cast<Standard_Integer> (aCtx->HasSelectedShape()));
4438     theDI << "Check if context has selected shape: " << hasSelected << "\n";
4439
4440     return 0;
4441   }
4442
4443   if (toPrintEntities)
4444   {
4445     theDI << "Detected entities:\n";
4446     Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector();
4447     SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager();
4448     for (aSelector->InitDetected(); aSelector->MoreDetected(); aSelector->NextDetected())
4449     {
4450       const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity();
4451       Handle(SelectMgr_EntityOwner) anOwner    = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
4452       Handle(AIS_InteractiveObject) anObj      = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
4453       gp_Trsf anInvTrsf;
4454       if (anObj->TransformPersistence().Flags)
4455       {
4456         const Graphic3d_Mat4d& aProjection = aMgr.ProjectionMatrix();
4457         const Graphic3d_Mat4d& aWorldView  = aMgr.WorldViewMatrix();
4458
4459         Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
4460         anInvTrsf.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
4461           aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
4462           aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
4463         anInvTrsf.Invert();
4464       }
4465       if (anObj->HasTransformation())
4466       {
4467         anInvTrsf = anObj->InversedTransformation() * anInvTrsf;
4468       }
4469       if (anEntity->HasInitLocation())
4470       {
4471         anInvTrsf = anEntity->InvInitLocation() * anInvTrsf;
4472       }
4473       const Standard_Integer aScale = anEntity->SensitivityFactor() < aSelector->PixelTolerance()
4474         ? anEntity->SensitivityFactor() : 1;
4475       const Standard_Boolean isToScaleAndTransform = anInvTrsf.Form() != gp_Identity || aScale != 1;
4476       SelectMgr_SelectingVolumeManager anEntMgr =
4477         isToScaleAndTransform ? aMgr.ScaleAndTransform (aScale, anInvTrsf)
4478                               : aMgr;
4479       SelectBasics_PickResult aResult;
4480       anEntity->Matches (anEntMgr, aResult);
4481       gp_Pnt aDetectedPnt = anInvTrsf.Form() == gp_Identity ?
4482         anEntMgr.DetectedPoint (aResult.Depth()) : anEntMgr.DetectedPoint (aResult.Depth()).Transformed (anInvTrsf.Inverted());
4483
4484       TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
4485       aName.LeftJustify (20, ' ');
4486       char anInfoStr[512];
4487       Sprintf (anInfoStr,
4488                " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f",
4489                aResult.Depth(),
4490                aResult.DistToGeomCenter(),
4491                aDetectedPnt.X(), aDetectedPnt.Y(), aDetectedPnt.Z());
4492       theDI << "  " << aName
4493             << anInfoStr
4494             << " (" << anEntity->DynamicType()->Name() << ")"
4495             << "\n";
4496
4497       Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
4498       if (!aBRepOwner.IsNull())
4499       {
4500         theDI << "                       Detected Shape: "
4501               << aBRepOwner->Shape().TShape()->DynamicType()->Name()
4502               << "\n";
4503       }
4504
4505       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast (anEntity);
4506       if (!aWire.IsNull())
4507       {
4508         Handle(Select3D_SensitiveEntity) aSen = aWire->GetLastDetected();
4509         theDI << "                       Detected Child: "
4510               << aSen->DynamicType()->Name()
4511               << "\n";
4512       }
4513     }
4514     return 0;
4515   }
4516
4517   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
4518   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
4519   {
4520     aDetected.Add (aCtx->DetectedCurrentObject());
4521   }
4522
4523   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
4524   if (theArgNb >= 2
4525    && !toShowAll)
4526   {
4527     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4528     {
4529       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
4530       if (!GetMapOfAIS().IsBound2 (anObjName))
4531       {
4532         theDI << anObjName << " doesn't exist!\n";
4533         continue;
4534       }
4535
4536       const Handle(Standard_Transient) anObjTrans = GetMapOfAIS().Find2 (anObjName);
4537       TCollection_AsciiString aName = anObjName;
4538       aName.LeftJustify (20, ' ');
4539       theDI << "  " << aName << " ";
4540       objInfo (aDetected, anObjTrans, theDI);
4541       theDI << "\n";
4542     }
4543     return 0;
4544   }
4545
4546   if (!aCtx->HasOpenedContext() && aCtx->NbSelected() > 0 && !toShowAll)
4547   {
4548     NCollection_DataMap<Handle(SelectMgr_EntityOwner), TopoDS_Shape> anOwnerShapeMap;
4549     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
4550     {
4551       const Handle(SelectMgr_EntityOwner) anOwner = aCtx->SelectedOwner();
4552       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
4553       // handle whole object selection
4554       if (anOwner == anObj->GlobalSelOwner())
4555       {
4556         TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
4557         aName.LeftJustify (20, ' ');
4558         theDI << aName << " ";
4559         objInfo (aDetected, anObj, theDI);
4560         theDI << "\n";
4561       }
4562     }
4563
4564     // process selected sub-shapes
4565     printLocalSelectionInfo (aCtx, theDI);
4566
4567     return 0;
4568   }
4569
4570   theDI << "Neutral-point state:\n";
4571   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4572        anObjIter.More(); anObjIter.Next())
4573   {
4574     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anObjIter.Key1());
4575     if (anObj.IsNull())
4576     {
4577       continue;
4578     }
4579
4580     TCollection_AsciiString aName = anObjIter.Key2();
4581     aName.LeftJustify (20, ' ');
4582     theDI << "  " << aName << " ";
4583     objInfo (aDetected, anObj, theDI);
4584     theDI << "\n";
4585   }
4586   printLocalSelectionInfo (aCtx, theDI);
4587   if (aCtx->HasOpenedContext())
4588     printLocalSelectionInfo (aCtx->LocalContext(), theDI);
4589   return 0;
4590 }
4591
4592 //=======================================================================
4593 //function : PickObjects
4594 //purpose  :
4595 //=======================================================================
4596 Standard_Boolean  ViewerTest::PickObjects(Handle(TColStd_HArray1OfTransient)& arr,
4597                                           const AIS_KindOfInteractive TheType,
4598                                           const Standard_Integer TheSignature,
4599                                           const Standard_Integer MaxPick)
4600 {
4601   Handle(AIS_InteractiveObject) IO;
4602   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
4603
4604   // step 1: prepare the data
4605   if(curindex !=0){
4606     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
4607     TheAISContext()->AddFilter(F1);
4608   }
4609
4610   // step 2 : wait for the selection...
4611   Standard_Integer NbPickGood (0),NbToReach(arr->Length());
4612   Standard_Integer NbPickFail(0);
4613   Standard_Integer argccc = 5;
4614   const char *bufff[] = { "A", "B", "C","D", "E" };
4615   const char **argvvv = (const char **) bufff;
4616
4617
4618   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
4619     while(ViewerMainLoop(argccc,argvvv)){}
4620     Standard_Integer NbStored = TheAISContext()->NbSelected();
4621     if(NbStored != NbPickGood)
4622       NbPickGood= NbStored;
4623     else
4624       NbPickFail++;
4625     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<endl;
4626   }
4627
4628   // step3 get result.
4629
4630   if (NbPickFail >= NbToReach)
4631     return Standard_False;
4632
4633   Standard_Integer i(0);
4634   for(TheAISContext()->InitSelected();
4635       TheAISContext()->MoreSelected();
4636       TheAISContext()->NextSelected()){
4637     i++;
4638     Handle(AIS_InteractiveObject) IO2 = TheAISContext()->SelectedInteractive();
4639     arr->SetValue(i,IO2);
4640   }
4641
4642
4643   if(curindex>0)
4644     TheAISContext()->CloseLocalContext(curindex);
4645
4646   return Standard_True;
4647 }
4648
4649
4650 //=======================================================================
4651 //function : PickObject
4652 //purpose  :
4653 //=======================================================================
4654 Handle(AIS_InteractiveObject) ViewerTest::PickObject(const AIS_KindOfInteractive TheType,
4655                                                      const Standard_Integer TheSignature,
4656                                                      const Standard_Integer MaxPick)
4657 {
4658   Handle(AIS_InteractiveObject) IO;
4659   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
4660
4661   // step 1: prepare the data
4662
4663   if(curindex !=0){
4664     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
4665     TheAISContext()->AddFilter(F1);
4666   }
4667
4668   // step 2 : wait for the selection...
4669   Standard_Boolean IsGood (Standard_False);
4670   Standard_Integer NbPick(0);
4671   Standard_Integer argccc = 5;
4672   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
4673   const char **argvvv = (const char **) bufff;
4674
4675
4676   while(!IsGood && NbPick<= MaxPick){
4677     while(ViewerMainLoop(argccc,argvvv)){}
4678     IsGood = (TheAISContext()->NbSelected()>0) ;
4679     NbPick++;
4680     cout<<"Nb Pick :"<<NbPick<<endl;
4681   }
4682
4683
4684   // step3 get result.
4685   if(IsGood){
4686     TheAISContext()->InitSelected();
4687     IO = TheAISContext()->SelectedInteractive();
4688   }
4689
4690   if(curindex!=0)
4691     TheAISContext()->CloseLocalContext(curindex);
4692   return IO;
4693 }
4694
4695 //=======================================================================
4696 //function : PickShape
4697 //purpose  : First Activate the rightmode + Put Filters to be able to
4698 //           pick objets that are of type <TheType>...
4699 //=======================================================================
4700
4701 TopoDS_Shape ViewerTest::PickShape(const TopAbs_ShapeEnum TheType,
4702                                    const Standard_Integer MaxPick)
4703 {
4704
4705   // step 1: prepare the data
4706
4707   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
4708   TopoDS_Shape result;
4709
4710   if(TheType==TopAbs_SHAPE){
4711     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
4712     TheAISContext()->AddFilter(F1);
4713   }
4714   else{
4715     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
4716     TheAISContext()->AddFilter(TF);
4717     TheAISContext()->ActivateStandardMode(TheType);
4718
4719   }
4720
4721
4722   // step 2 : wait for the selection...
4723   Standard_Boolean NoShape (Standard_True);
4724   Standard_Integer NbPick(0);
4725   Standard_Integer argccc = 5;
4726   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
4727   const char **argvvv = (const char **) bufff;
4728
4729
4730   while(NoShape && NbPick<= MaxPick){
4731     while(ViewerMainLoop(argccc,argvvv)){}
4732     NoShape = (TheAISContext()->NbSelected()==0) ;
4733     NbPick++;
4734     cout<<"Nb Pick :"<<NbPick<<endl;
4735   }
4736
4737   // step3 get result.
4738
4739   if(!NoShape){
4740
4741     TheAISContext()->InitSelected();
4742     if(TheAISContext()->HasSelectedShape())
4743       result = TheAISContext()->SelectedShape();
4744     else{
4745       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4746       result = Handle(AIS_Shape)::DownCast (IO)->Shape();
4747     }
4748   }
4749
4750   if(curindex>0)
4751     TheAISContext()->CloseLocalContext(curindex);
4752
4753   return result;
4754 }
4755
4756
4757 //=======================================================================
4758 //function : PickShapes
4759 //purpose  :
4760 //=======================================================================
4761 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum TheType,
4762                                          Handle(TopTools_HArray1OfShape)& thearr,
4763                                          const Standard_Integer MaxPick)
4764 {
4765
4766   Standard_Integer Taille = thearr->Length();
4767   if(Taille>1)
4768     cout<<" WARNING : Pick with Shift+ MB1 for Selection of more than 1 object\n";
4769
4770   // step 1: prepare the data
4771   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
4772   if(TheType==TopAbs_SHAPE){
4773     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
4774     TheAISContext()->AddFilter(F1);
4775   }
4776   else{
4777     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
4778     TheAISContext()->AddFilter(TF);
4779     TheAISContext()->ActivateStandardMode(TheType);
4780
4781   }
4782
4783   // step 2 : wait for the selection...
4784   Standard_Integer NbPickGood (0),NbToReach(thearr->Length());
4785   Standard_Integer NbPickFail(0);
4786   Standard_Integer argccc = 5;
4787   const char *bufff[] = { "A", "B", "C","D", "E" };
4788   const char **argvvv = (const char **) bufff;
4789
4790
4791   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
4792     while(ViewerMainLoop(argccc,argvvv)){}
4793     Standard_Integer NbStored = TheAISContext()->NbSelected();
4794     if (NbStored != NbPickGood)
4795       NbPickGood= NbStored;
4796     else
4797       NbPickFail++;
4798     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<"\n";
4799   }
4800
4801   // step3 get result.
4802
4803   if (NbPickFail >= NbToReach)
4804     return Standard_False;
4805
4806   Standard_Integer i(0);
4807   for(TheAISContext()->InitSelected();TheAISContext()->MoreSelected();TheAISContext()->NextSelected()){
4808     i++;
4809     if(TheAISContext()->HasSelectedShape())
4810       thearr->SetValue(i,TheAISContext()->SelectedShape());
4811     else{
4812       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4813       thearr->SetValue(i,Handle(AIS_Shape)::DownCast (IO)->Shape());
4814     }
4815   }
4816
4817   TheAISContext()->CloseLocalContext(curindex);
4818   return Standard_True;
4819 }
4820
4821
4822 //=======================================================================
4823 //function : VPickShape
4824 //purpose  :
4825 //=======================================================================
4826 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4827 {
4828   TopoDS_Shape PickSh;
4829   TopAbs_ShapeEnum theType = TopAbs_COMPOUND;
4830
4831   if(argc==1)
4832     theType = TopAbs_SHAPE;
4833   else{
4834     if(!strcasecmp(argv[1],"V" )) theType = TopAbs_VERTEX;
4835     else if (!strcasecmp(argv[1],"E" )) theType = TopAbs_EDGE;
4836     else if (!strcasecmp(argv[1],"W" )) theType = TopAbs_WIRE;
4837     else if (!strcasecmp(argv[1],"F" )) theType = TopAbs_FACE;
4838     else if(!strcasecmp(argv[1],"SHAPE" )) theType = TopAbs_SHAPE;
4839     else if (!strcasecmp(argv[1],"SHELL" )) theType = TopAbs_SHELL;
4840     else if (!strcasecmp(argv[1],"SOLID" )) theType = TopAbs_SOLID;
4841   }
4842
4843   static Standard_Integer nbOfSub[8]={0,0,0,0,0,0,0,0};
4844   static TCollection_AsciiString nameType[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
4845
4846   TCollection_AsciiString name;
4847
4848
4849   Standard_Integer NbToPick = argc>2 ? argc-2 : 1;
4850   if(NbToPick==1){
4851     PickSh = ViewerTest::PickShape(theType);
4852
4853     if(PickSh.IsNull())
4854       return 1;
4855     if(argc>2){
4856       name += argv[2];
4857     }
4858     else{
4859
4860       if(!PickSh.IsNull()){
4861         nbOfSub[Standard_Integer(theType)]++;
4862         name += "Picked_";
4863         name += nameType[Standard_Integer(theType)];
4864         TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
4865         name +="_";
4866         name+=indxstring;
4867       }
4868     }
4869     // si on avait une petite methode pour voir si la shape
4870     // est deja dans la Double map, ca eviterait de creer....
4871     DBRep::Set(name.ToCString(),PickSh);
4872
4873     Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
4874     GetMapOfAIS().Bind(newsh, name);
4875     TheAISContext()->Display(newsh);
4876     di<<"Nom de la shape pickee : "<<name.ToCString()<<"\n";
4877   }
4878
4879   // Plusieurs objets a picker, vite vite vite....
4880   //
4881   else{
4882     Standard_Boolean autonaming = !strcasecmp(argv[2],".");
4883     Handle(TopTools_HArray1OfShape) arr = new TopTools_HArray1OfShape(1,NbToPick);
4884     if(ViewerTest::PickShapes(theType,arr)){
4885       for(Standard_Integer i=1;i<=NbToPick;i++){
4886         PickSh = arr->Value(i);
4887         if(!PickSh.IsNull()){
4888           if(autonaming){
4889             nbOfSub[Standard_Integer(theType)]++;
4890             name.Clear();
4891             name += "Picked_";
4892             name += nameType[Standard_Integer(theType)];
4893             TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
4894             name +="_";
4895             name+=indxstring;
4896           }
4897         }
4898         else
4899           name = argv[1+i];
4900
4901         DBRep::Set(name.ToCString(),PickSh);
4902         Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
4903         GetMapOfAIS().Bind(newsh, name);
4904         di<<"display of picke shape #"<<i<<" - nom : "<<name.ToCString()<<"\n";
4905         TheAISContext()->Display(newsh);
4906
4907       }
4908     }
4909   }
4910   return 0;
4911 }
4912
4913 //=======================================================================
4914 //function : VPickSelected
4915 //purpose  :
4916 //=======================================================================
4917 static int VPickSelected (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgs)
4918 {
4919   static Standard_Integer aCount = 0;
4920   TCollection_AsciiString aName = "PickedShape_";
4921
4922   if (theArgNb > 1)
4923   {
4924     aName = theArgs[1];
4925   }
4926   else
4927   {
4928     aName = aName + aCount++ + "_";
4929   }
4930
4931   Standard_Integer anIdx = 0;
4932   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected(), ++anIdx)
4933   {
4934     TopoDS_Shape aShape;
4935     if (TheAISContext()->HasSelectedShape())
4936     {
4937       aShape = TheAISContext()->SelectedShape();
4938     }
4939     else
4940     {
4941       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4942       aShape = Handle(AIS_Shape)::DownCast (IO)->Shape();
4943     }
4944
4945     TCollection_AsciiString aCurrentName = aName;
4946     if (anIdx > 0)
4947     {
4948       aCurrentName += anIdx;
4949     }
4950
4951     DBRep::Set ((aCurrentName).ToCString(), aShape);
4952
4953     Handle(AIS_Shape) aNewShape = new AIS_Shape (aShape);
4954     GetMapOfAIS().Bind (aNewShape, aCurrentName);
4955     TheAISContext()->Display (aNewShape);
4956   }
4957
4958   return 0;
4959 }
4960
4961 //=======================================================================
4962 //function : list of known objects
4963 //purpose  :
4964 //=======================================================================
4965 static int VIOTypes( Draw_Interpretor& di, Standard_Integer , const char** )
4966 {
4967   //                             1234567890         12345678901234567         123456789
4968   TCollection_AsciiString Colum [3]={"Standard Types","Type Of Object","Signature"};
4969   TCollection_AsciiString BlankLine(64,'_');
4970   Standard_Integer i ;
4971
4972   di<<"/n"<<BlankLine.ToCString()<<"\n";
4973
4974   for( i =0;i<=2;i++)
4975     Colum[i].Center(20,' ');
4976   for(i=0;i<=2;i++)
4977     di<<"|"<<Colum[i].ToCString();
4978   di<<"|\n";
4979
4980   di<<BlankLine.ToCString()<<"\n";
4981
4982   //  TCollection_AsciiString thetypes[5]={"Datum","Shape","Object","Relation","None"};
4983   const char ** names = GetTypeNames();
4984
4985   TCollection_AsciiString curstring;
4986   TCollection_AsciiString curcolum[3];
4987
4988
4989   // les objets de type Datum..
4990   curcolum[1]+="Datum";
4991   for(i =0;i<=6;i++){
4992     curcolum[0].Clear();
4993     curcolum[0] += names[i];
4994
4995     curcolum[2].Clear();
4996     curcolum[2]+=TCollection_AsciiString(i+1);
4997
4998     for(Standard_Integer j =0;j<=2;j++){
4999       curcolum[j].Center(20,' ');
5000       di<<"|"<<curcolum[j].ToCString();
5001     }
5002     di<<"|\n";
5003   }
5004   di<<BlankLine.ToCString()<<"\n";
5005
5006   // les objets de type shape
5007   curcolum[1].Clear();
5008   curcolum[1]+="Shape";
5009   curcolum[1].Center(20,' ');
5010
5011   for(i=0;i<=2;i++){
5012     curcolum[0].Clear();
5013     curcolum[0] += names[7+i];
5014     curcolum[2].Clear();
5015     curcolum[2]+=TCollection_AsciiString(i);
5016
5017     for(Standard_Integer j =0;j<=2;j++){
5018       curcolum[j].Center(20,' ');
5019       di<<"|"<<curcolum[j].ToCString();
5020     }
5021     di<<"|\n";
5022   }
5023   di<<BlankLine.ToCString()<<"\n";
5024   // les IO de type objet...
5025   curcolum[1].Clear();
5026   curcolum[1]+="Object";
5027   curcolum[1].Center(20,' ');
5028   for(i=0;i<=1;i++){
5029     curcolum[0].Clear();
5030     curcolum[0] += names[10+i];
5031     curcolum[2].Clear();
5032     curcolum[2]+=TCollection_AsciiString(i);
5033
5034     for(Standard_Integer j =0;j<=2;j++){
5035       curcolum[j].Center(20,' ');
5036       di<<"|"<<curcolum[j].ToCString();
5037     }
5038     di<<"|\n";
5039   }
5040   di<<BlankLine.ToCString()<<"\n";
5041   // les contraintes et dimensions.
5042   // pour l'instant on separe juste contraintes et dimensions...
5043   // plus tard, on detaillera toutes les sortes...
5044   curcolum[1].Clear();
5045   curcolum[1]+="Relation";
5046   curcolum[1].Center(20,' ');
5047   for(i=0;i<=1;i++){
5048     curcolum[0].Clear();
5049     curcolum[0] += names[12+i];
5050     curcolum[2].Clear();
5051     curcolum[2]+=TCollection_AsciiString(i);
5052
5053     for(Standard_Integer j =0;j<=2;j++){
5054       curcolum[j].Center(20,' ');
5055       di<<"|"<<curcolum[j].ToCString();
5056     }
5057     di<<"|\n";
5058   }
5059   di<<BlankLine.ToCString()<<"\n";
5060
5061
5062   return 0;
5063 }
5064
5065
5066 static int VEraseType( Draw_Interpretor& , Standard_Integer argc, const char** argv)
5067 {
5068   if(argc!=2) return 1;
5069
5070   AIS_KindOfInteractive TheType;
5071   Standard_Integer TheSign(-1);
5072   GetTypeAndSignfromString(argv[1],TheType,TheSign);
5073
5074
5075   AIS_ListOfInteractive LIO;
5076
5077   // en attendant l'amelioration ais pour les dimensions...
5078   //
5079   Standard_Integer dimension_status(-1);
5080   if(TheType==AIS_KOI_Relation){
5081     dimension_status = TheSign ==1 ? 1 : 0;
5082     TheSign=-1;
5083   }
5084
5085   TheAISContext()->DisplayedObjects(TheType,TheSign,LIO);
5086   Handle(AIS_InteractiveObject) curio;
5087   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
5088     curio  = it.Value();
5089
5090     if(dimension_status == -1)
5091       TheAISContext()->Erase(curio,Standard_False);
5092     else {
5093       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
5094       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
5095           (dimension_status==1 && KOD != AIS_KOD_NONE))
5096         TheAISContext()->Erase(curio,Standard_False);
5097     }
5098   }
5099   TheAISContext()->UpdateCurrentViewer();
5100   return 0;
5101 }
5102 static int VDisplayType(Draw_Interpretor& , Standard_Integer argc, const char** argv)
5103 {
5104   if(argc!=2) return 1;
5105
5106   AIS_KindOfInteractive TheType;
5107   Standard_Integer TheSign(-1);
5108   GetTypeAndSignfromString(argv[1],TheType,TheSign);
5109
5110   // en attendant l'amelioration ais pour les dimensions...
5111   //
5112   Standard_Integer dimension_status(-1);
5113   if(TheType==AIS_KOI_Relation){
5114     dimension_status = TheSign ==1 ? 1 : 0;
5115     TheSign=-1;
5116   }
5117
5118   AIS_ListOfInteractive LIO;
5119   TheAISContext()->ObjectsInside(LIO,TheType,TheSign);
5120   Handle(AIS_InteractiveObject) curio;
5121   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
5122     curio  = it.Value();
5123     if(dimension_status == -1)
5124       TheAISContext()->Display(curio,Standard_False);
5125     else {
5126       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
5127       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
5128           (dimension_status==1 && KOD != AIS_KOD_NONE))
5129         TheAISContext()->Display(curio,Standard_False);
5130     }
5131
5132   }
5133
5134   TheAISContext()->UpdateCurrentViewer();
5135   return 0;
5136 }
5137
5138 static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a)
5139 {
5140   ifstream s(a[1]);
5141   BRep_Builder builder;
5142   TopoDS_Shape shape;
5143   BRepTools::Read(shape, s, builder);
5144   DBRep::Set(a[1], shape);
5145   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
5146   Handle(AIS_Shape) ais = new AIS_Shape(shape);
5147   Ctx->Display(ais);
5148   return 0;
5149 }
5150
5151 //===============================================================================================
5152 //function : VBsdf
5153 //purpose  :
5154 //===============================================================================================
5155 static int VBsdf (Draw_Interpretor& theDi,
5156                   Standard_Integer  theArgsNb,
5157                   const char**      theArgVec)
5158 {
5159   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
5160   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5161   if (aView.IsNull()
5162    || aViewer.IsNull())
5163   {
5164     std::cerr << "No active viewer!\n";
5165     return 1;
5166   }
5167
5168   ViewerTest_CmdParser aCmd;
5169
5170   aCmd.AddDescription ("Adjusts parameters of material BSDF:");
5171   aCmd.AddOption ("print|echo|p", "Print BSDF");
5172
5173   aCmd.AddOption ("kd", "Weight of the Lambertian BRDF");
5174   aCmd.AddOption ("kr", "Weight of the reflection BRDF");
5175   aCmd.AddOption ("kt", "Weight of the transmission BTDF");
5176   aCmd.AddOption ("ks", "Weight of the glossy Blinn BRDF");
5177   aCmd.AddOption ("le", "Self-emitted radiance");
5178
5179   aCmd.AddOption ("fresnel|f", "Fresnel coefficients; Allowed fresnel formats are: Constant x, Schlick x y z, Dielectric x, Conductor x y");
5180
5181   aCmd.AddOption ("roughness|r",    "Roughness of material (Blinn's exponent)");
5182   aCmd.AddOption ("absorpCoeff|af", "Absorption coeff (only for transparent material)");
5183   aCmd.AddOption ("absorpColor|ac", "Absorption color (only for transparent material)");
5184
5185   aCmd.AddOption ("normalize|n", "Normalize BSDF coefficients");
5186
5187   aCmd.Parse (theArgsNb, theArgVec);
5188
5189   if (aCmd.HasOption ("help"))
5190   {
5191     theDi.PrintHelp (theArgVec[0]);
5192     return 0;
5193   }
5194
5195   TCollection_AsciiString aName (aCmd.Arg ("", 0).c_str());
5196
5197   // find object
5198   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
5199   if (!aMap.IsBound2 (aName) )
5200   {
5201     std::cerr << "Use 'vdisplay' before\n";
5202     return 1;
5203   }
5204
5205   Handle(AIS_InteractiveObject) anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
5206   Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
5207   Graphic3d_BSDF aBSDF = aMaterial.BSDF();
5208
5209   if (aCmd.HasOption ("print"))
5210   {
5211     Graphic3d_Vec4 aFresnel = aBSDF.Fresnel.Serialize();
5212
5213     std::cout << "\n"
5214       << "Kd:               " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
5215       << "Kr:               " << aBSDF.Kr.r() << ", " << aBSDF.Kr.g() << ", " << aBSDF.Kr.b() << "\n"
5216       << "Kt:               " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
5217       << "Ks:               " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
5218       << "Le:               " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n"
5219       << "Fresnel:          ";
5220
5221     if (aFresnel.x() >= 0.f)
5222     {
5223       std::cout
5224         << "|Schlick| " << aFresnel.x() << ", " << aFresnel.y() << ", " << aFresnel.z() << "\n";
5225     }
5226     else if (aFresnel.x() >= -1.5f)
5227     {
5228       std::cout
5229         << "|Constant| " << aFresnel.z() << "\n";
5230     }
5231     else if (aFresnel.x() >= -2.5f)
5232     {
5233       std::cout
5234         << "|Conductor| " << aFresnel.y() << ", " << aFresnel.z() << "\n";
5235     }
5236     else
5237     {
5238       std::cout
5239         << "|Dielectric| " << aFresnel.y() << "\n";
5240     }
5241
5242
5243     std::cout 
5244       << "Roughness:        " << aBSDF.Roughness           << "\n"
5245       << "Absorption coeff: " << aBSDF.AbsorptionCoeff     << "\n"
5246       << "Absorption color: " << aBSDF.AbsorptionColor.r() << ", "
5247                               << aBSDF.AbsorptionColor.g() << ", "
5248                               << aBSDF.AbsorptionColor.b() << "\n";
5249
5250     return 0;
5251   }
5252
5253   if (aCmd.HasOption ("roughness", 1, Standard_True))
5254   {
5255     aCmd.Arg ("roughness", 0);
5256     aBSDF.Roughness = aCmd.ArgFloat ("roughness");
5257   }
5258
5259   if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
5260   {
5261     aBSDF.AbsorptionCoeff = aCmd.ArgFloat ("absorpCoeff");
5262   }
5263
5264   if (aCmd.HasOption ("absorpColor", 3, Standard_True))
5265   {
5266     aBSDF.AbsorptionColor = aCmd.ArgVec3f ("absorpColor");
5267   }
5268
5269   if (aCmd.HasOption ("kd", 3))
5270   {
5271     aBSDF.Kd = aCmd.ArgVec3f ("kd");
5272   }
5273   else if (aCmd.HasOption ("kd", 1, Standard_True))
5274   {
5275     aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
5276   }
5277
5278   if (aCmd.HasOption ("kr", 3))
5279   {
5280     aBSDF.Kr = aCmd.ArgVec3f ("kr");
5281   }
5282   else if (aCmd.HasOption ("kr", 1, Standard_True))
5283   {
5284     aBSDF.Kr = Graphic3d_Vec3 (aCmd.ArgFloat ("kr"));
5285   }
5286
5287   if (aCmd.HasOption ("kt", 3))
5288   {
5289     aBSDF.Kt = aCmd.ArgVec3f ("kt");
5290   }
5291   else if (aCmd.HasOption ("kt", 1, Standard_True))
5292   {
5293     aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
5294   }
5295
5296   if (aCmd.HasOption ("ks", 3))
5297   {
5298     aBSDF.Ks = aCmd.ArgVec3f ("ks");
5299   }
5300   else if (aCmd.HasOption ("ks", 1, Standard_True))
5301   {
5302     aBSDF.Ks = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
5303   }
5304
5305   if (aCmd.HasOption ("le", 3))
5306   {
5307     aBSDF.Le = aCmd.ArgVec3f ("le");
5308   }
5309   else if (aCmd.HasOption ("le", 1, Standard_True))
5310   {
5311     aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
5312   }
5313
5314   const std::string aFresnelErrorMessage =
5315     "Error! Wrong Fresnel type. Allowed types are: Constant x, Schlick x y z, Dielectric x, Conductor x y.\n";
5316
5317   if (aCmd.HasOption ("fresnel", 4)) // Schlick: type, x, y ,z
5318   {
5319     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5320     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5321
5322     if (aFresnelType == "schlick")
5323     {
5324       aBSDF.Fresnel = Graphic3d_Fresnel::CreateSchlick (
5325         Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
5326                         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())),
5327                         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 3).c_str()))));
5328     }
5329     else
5330     {
5331       std::cout << aFresnelErrorMessage;
5332     }
5333   }
5334   else if (aCmd.HasOption ("fresnel", 3)) // Conductor: type, x, y
5335   {
5336     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5337     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5338
5339     if (aFresnelType == "conductor")
5340     {
5341       aBSDF.Fresnel = Graphic3d_Fresnel::CreateConductor (
5342         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
5343         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())));
5344     }
5345     else
5346     {
5347       std::cout << aFresnelErrorMessage;
5348     }
5349   }
5350   else if (aCmd.HasOption ("fresnel", 2)) // Dielectric, Constant: type, x
5351   {
5352     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5353     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5354
5355     if (aFresnelType == "dielectric")
5356     {
5357       aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (
5358         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
5359     }
5360     else if (aFresnelType == "constant")
5361     {
5362       aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (
5363         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
5364     }
5365     else
5366     {
5367       std::cout << aFresnelErrorMessage;
5368     }
5369   }
5370
5371   if (aCmd.HasOption ("normalize"))
5372   {
5373     aBSDF.Normalize();
5374   }
5375
5376   aMaterial.SetBSDF (aBSDF);
5377   anIObj->SetMaterial (aMaterial);
5378
5379   aView->Redraw();
5380
5381   return 0;
5382 }
5383
5384 //==============================================================================
5385 //function : VLoadSelection
5386 //purpose  : Adds given objects to map of AIS and loads selection primitives for them
5387 //==============================================================================
5388 static Standard_Integer VLoadSelection (Draw_Interpretor& /*theDi*/,
5389                                         Standard_Integer theArgNb,
5390                                         const char** theArgVec)
5391 {
5392   if (theArgNb < 2)
5393   {
5394     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5395     return 1;
5396   }
5397
5398   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5399   if (aCtx.IsNull())
5400   {
5401     ViewerTest::ViewerInit();
5402     aCtx = ViewerTest::GetAISContext();
5403   }
5404
5405   // Parse input arguments
5406   TColStd_SequenceOfAsciiString aNamesOfIO;
5407   Standard_Boolean isLocal = Standard_False;
5408   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5409   {
5410     const TCollection_AsciiString aName     = theArgVec[anArgIter];
5411     TCollection_AsciiString       aNameCase = aName;
5412     aNameCase.LowerCase();
5413     if (aNameCase == "-local")
5414     {
5415       isLocal = Standard_True;
5416     }
5417     else
5418     {
5419       aNamesOfIO.Append (aName);
5420     }
5421   }
5422
5423   if (aNamesOfIO.IsEmpty())
5424   {
5425     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5426     return 1;
5427   }
5428
5429   // Prepare context
5430   if (isLocal && !aCtx->HasOpenedContext())
5431   {
5432     aCtx->OpenLocalContext (Standard_False);
5433   }
5434   else if (!isLocal && aCtx->HasOpenedContext())
5435   {
5436     aCtx->CloseAllContexts (Standard_False);
5437   }
5438
5439   // Load selection of interactive objects
5440   for (Standard_Integer anIter = 1; anIter <= aNamesOfIO.Length(); ++anIter)
5441   {
5442     const TCollection_AsciiString& aName = aNamesOfIO.Value (anIter);
5443
5444     Handle(AIS_InteractiveObject) aShape;
5445     if (GetMapOfAIS().IsBound2 (aName))
5446       aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
5447     else
5448       aShape = GetAISShapeFromName (aName.ToCString());
5449
5450     if (!aShape.IsNull())
5451     {
5452       if (!GetMapOfAIS().IsBound2 (aName))
5453       {
5454         GetMapOfAIS().Bind (aShape, aName);
5455       }
5456
5457       aCtx->Load (aShape, -1, Standard_False);
5458       aCtx->Activate (aShape, aShape->GlobalSelectionMode(), Standard_True);
5459     }
5460   }
5461
5462   return 0;
5463 }
5464
5465 //==============================================================================
5466 //function : VAutoActivateSelection
5467 //purpose  : Activates or deactivates auto computation of selection
5468 //==============================================================================
5469 static int VAutoActivateSelection (Draw_Interpretor& theDi,
5470                                    Standard_Integer theArgNb,
5471                                    const char** theArgVec)
5472 {
5473
5474   if (theArgNb > 2)
5475   {
5476     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5477     return 1;
5478   }
5479
5480   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5481   if (aCtx.IsNull())
5482   {
5483     ViewerTest::ViewerInit();
5484     aCtx = ViewerTest::GetAISContext();
5485   }
5486
5487   if (theArgNb == 1)
5488   {
5489     TCollection_AsciiString aSelActivationString;
5490     if (aCtx->GetAutoActivateSelection())
5491     {
5492       aSelActivationString.Copy ("ON");
5493     }
5494     else
5495     {
5496       aSelActivationString.Copy ("OFF");
5497     }
5498
5499     theDi << "Auto activation of selection is: " << aSelActivationString << "\n";
5500   }
5501   else
5502   {
5503     Standard_Boolean toActivate = Draw::Atoi (theArgVec[1]);
5504     aCtx->SetAutoActivateSelection (toActivate);
5505   }
5506
5507   return 0;
5508 }
5509
5510 //==============================================================================
5511 //function : ViewerTest::Commands
5512 //purpose  : Add all the viewer command in the Draw_Interpretor
5513 //==============================================================================
5514
5515 void ViewerTest::Commands(Draw_Interpretor& theCommands)
5516 {
5517   ViewerTest::ViewerCommands(theCommands);
5518   ViewerTest::RelationCommands(theCommands);
5519   ViewerTest::ObjectCommands(theCommands);
5520   ViewerTest::FilletCommands(theCommands);
5521   ViewerTest::OpenGlCommands(theCommands);
5522
5523   const char *group = "AIS_Display";
5524
5525   // display
5526   theCommands.Add("visos",
5527       "visos [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]\n"
5528       "\tIf last 3 optional parameters are not set prints numbers of U-, V- isolines and IsoOnPlane.\n",
5529       __FILE__, visos, group);
5530
5531   theCommands.Add("vdisplay",
5532               "vdisplay [-noupdate|-update] [-local] [-mutable] [-neutral]"
5533       "\n\t\t:          [-trsfPers {pan|zoom|rotate|trihedron|full|none}=none] [-trsfPersPos X Y [Z]] [-3d|-2d|-2dTopDown]"
5534       "\n\t\t:          [-dispMode mode] [-highMode mode]"
5535       "\n\t\t:          [-layer index] [-top|-topmost|-overlay|-underlay]"
5536       "\n\t\t:          [-redisplay]"
5537       "\n\t\t:          name1 [name2] ... [name n]"
5538       "\n\t\t: Displays named objects."
5539       "\n\t\t: Option -local enables displaying of objects in local"
5540       "\n\t\t: selection context. Local selection context will be opened"
5541       "\n\t\t: if there is not any."
5542       "\n\t\t:  -noupdate    suppresses viewer redraw call."
5543       "\n\t\t:  -mutable     enables optimizations for mutable objects."
5544       "\n\t\t:  -neutral     draws objects in main viewer."
5545       "\n\t\t:  -layer       sets z-layer for objects. It can use -overlay|-underlay|-top|-topmost instead of -layer index for the default z-layers."
5546       "\n\t\t:  -top         draws objects on top of main presentations but below topmost."
5547       "\n\t\t:  -topmost     draws in overlay for 3D presentations with independent Depth."
5548       "\n\t\t:  -overlay     draws objects in overlay for 2D presentations (On-Screen-Display)."
5549       "\n\t\t:  -underlay    draws objects in underlay for 2D presentations (On-Screen-Display)."
5550       "\n\t\t:  -selectable|-noselect controls selection of objects."
5551       "\n\t\t:  -trsfPers    sets a transform persistence flags. Flag 'full' is pan, zoom and rotate."
5552       "\n\t\t:  -trsfPersPos sets an anchor point for transform persistence."
5553       "\n\t\t:  -2d|-2dTopDown displays object in screen coordinates."
5554       "\n\t\t:  -dispmode sets display mode for objects."
5555       "\n\t\t:  -highmode sets hilight mode for objects."
5556       "\n\t\t:  -redisplay recomputes presentation of objects.",
5557       __FILE__, VDisplay2, group);
5558
5559   theCommands.Add ("vupdate",
5560       "vupdate name1 [name2] ... [name n]"
5561       "\n\t\t: Updates named objects in interactive context",
5562       __FILE__, VUpdate, group);
5563
5564   theCommands.Add("verase",
5565       "verase [-noupdate|-update] [-local] [name1] ...  [name n]"
5566       "\n\t\t: Erases selected or named objects."
5567       "\n\t\t: If there are no selected or named objects the whole viewer is erased."
5568       "\n\t\t: Option -local enables erasing of selected or named objects without"
5569       "\n\t\t: closing local selection context.",
5570       __FILE__, VErase, group);
5571
5572   theCommands.Add("vremove",
5573       "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ...  [name n]"
5574       "or vremove [-context] -all to remove all objects"
5575       "\n\t\t: Removes selected or named objects."
5576       "\n\t\t  If -context is in arguments, the objects are not deleted"
5577       "\n\t\t  from the map of objects and names."
5578       "\n\t\t: Option -local enables removing of selected or named objects without"
5579       "\n\t\t: closing local selection context. Empty local selection context will be"
5580       "\n\t\t: closed."
5581       "\n\t\t: Option -noupdate suppresses viewer redraw call."
5582       "\n\t\t: Option -noinfo suppresses displaying the list of removed objects.",
5583       __FILE__, VRemove, group);
5584
5585   theCommands.Add("vdonly",
5586                   "vdonly [-noupdate|-update] [name1] ...  [name n]"
5587       "\n\t\t: Displays only selected or named objects",
5588                   __FILE__,VDonly2,group);
5589
5590   theCommands.Add("vdisplayall",
5591       "vidsplayall [-local]"
5592       "\n\t\t: Displays all erased interactive objects (see vdir and vstate)."
5593       "\n\t\t: Option -local enables displaying of the objects in local"
5594       "\n\t\t: selection context.",
5595       __FILE__, VDisplayAll, group);
5596
5597   theCommands.Add("veraseall",
5598       "veraseall [-local]"
5599       "\n\t\t: Erases all objects displayed in the viewer."
5600       "\n\t\t: Option -local enables erasing of the objects in local"
5601       "\n\t\t: selection context.",
5602       __FILE__, VErase, group);
5603
5604   theCommands.Add("verasetype",
5605       "verasetype <Type>"
5606       "\n\t\t: Erase all the displayed objects of one given kind (see vtypes)",
5607       __FILE__, VEraseType, group);
5608   theCommands.Add("vbounding",
5609               "vbounding [-noupdate|-update] [-mode] name1 [name2 [...]]"
5610       "\n\t\t:           [-print] [-hide]"
5611       "\n\t\t: Temporarily display bounding box of specified Interactive"
5612       "\n\t\t: Objects, or print it to console if -print is specified."
5613       "\n\t\t: Already displayed box might be hidden by -hide option.",
5614                   __FILE__,VBounding,group);
5615
5616   theCommands.Add("vdisplaytype",
5617                   "vdisplaytype        : vdisplaytype <Type> <Signature> \n\t display all the objects of one given kind (see vtypes) which are stored the AISContext ",
5618                   __FILE__,VDisplayType,group);
5619
5620   theCommands.Add("vdisplaymode",
5621                   "vdispmode       : vdispmode  [name] mode(1,2,..) : no name -> on selected objects ",
5622                   __FILE__,VDispMode,group);
5623
5624   theCommands.Add("verasemode",
5625                   "verasemode      : verasemode [name] mode(1,2,..) : no name -> on selected objects",
5626                   __FILE__,VDispMode,group);
5627
5628   theCommands.Add("vsetdispmode",
5629                   "vsetdispmode [name] mode(1,2,..)"
5630       "\n\t\t: Sets display mode for all, selected or named objects.",
5631                   __FILE__,VDispMode,group);
5632
5633   theCommands.Add("vunsetdispmode",
5634                   "vunsetdispmode [name]"
5635       "\n\t\t: Unsets custom display mode for selected or named objects.",
5636                   __FILE__,VDispMode,group);
5637
5638   theCommands.Add("vdir",
5639                   "Lists all objects displayed in 3D viewer",
5640                   __FILE__,VDir,group);
5641
5642 #ifdef HAVE_FREEIMAGE
5643   #define DUMP_FORMATS "{png|bmp|jpg|gif}"
5644 #else
5645   #define DUMP_FORMATS "{ppm}"
5646 #endif
5647   theCommands.Add("vdump",
5648               "vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
5649       "\n\t\t:       [-buffer rgb|rgba|depth=rgb]"
5650       "\n\t\t:       [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
5651       "\n\t\t: Dumps content of the active view into image file",
5652                   __FILE__,VDump,group);
5653
5654   theCommands.Add("vsub",      "vsub 0/1 (off/on) [obj]        : Subintensity(on/off) of selected objects",
5655                   __FILE__,VSubInt,group);
5656
5657   theCommands.Add("vaspects",
5658               "vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults]"
5659       "\n\t\t:          [-setVisibility 0|1]"
5660       "\n\t\t:          [-setColor ColorName] [-setcolor R G B] [-unsetColor]"
5661       "\n\t\t:          [-setMaterial MatName] [-unsetMaterial]"
5662       "\n\t\t:          [-setTransparency Transp] [-unsetTransparency]"
5663       "\n\t\t:          [-setWidth LineWidth] [-unsetWidth]"
5664       "\n\t\t:          [-setLineType {solid|dash|dot|dotDash}] [-unsetLineType]"
5665       "\n\t\t:          [-freeBoundary {off/on | 0/1}]"
5666       "\n\t\t:          [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]"
5667       "\n\t\t:          [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]"
5668       "\n\t\t:          [-subshapes subname1 [subname2 [...]]]"
5669       "\n\t\t:          [-isoontriangulation 0|1]"
5670       "\n\t\t:          [-setMaxParamValue {value}]"
5671       "\n\t\t:          [-setSensitivity {selection_mode} {value}]"
5672       "\n\t\t: Manage presentation properties of all, selected or named objects."
5673       "\n\t\t: When -subshapes is specified than following properties will be"
5674       "\n\t\t: assigned to specified sub-shapes."
5675       "\n\t\t: When -defaults is specified than presentation properties will be"
5676       "\n\t\t: assigned to all objects that have not their own specified properties"
5677       "\n\t\t: and to all objects to be displayed in the future."
5678       "\n\t\t: If -defaults is used there should not be any objects' names and -subshapes specifier.",
5679                   __FILE__,VAspects,group);
5680
5681   theCommands.Add("vsetcolor",
5682       "vsetcolor [-noupdate|-update] [name] ColorName"
5683       "\n\t\t: Sets color for all, selected or named objects."
5684       "\n\t\t: Alias for vaspects -setcolor [name] ColorName.",
5685                   __FILE__,VAspects,group);
5686
5687   theCommands.Add("vunsetcolor",
5688                   "vunsetcolor [-noupdate|-update] [name]"
5689       "\n\t\t: Resets color for all, selected or named objects."
5690       "\n\t\t: Alias for vaspects -unsetcolor [name].",
5691                   __FILE__,VAspects,group);
5692
5693   theCommands.Add("vsettransparency",
5694                   "vsettransparency [-noupdate|-update] [name] Coefficient"
5695       "\n\t\t: Sets transparency for all, selected or named objects."
5696       "\n\t\t: The Coefficient may be between 0.0 (opaque) and 1.0 (fully transparent)."
5697       "\n\t\t: Alias for vaspects -settransp [name] Coefficient.",
5698                   __FILE__,VAspects,group);
5699
5700   theCommands.Add("vunsettransparency",
5701                   "vunsettransparency [-noupdate|-update] [name]"
5702       "\n\t\t: Resets transparency for all, selected or named objects."
5703       "\n\t\t: Alias for vaspects -unsettransp [name].",
5704                   __FILE__,VAspects,group);
5705
5706   theCommands.Add("vsetmaterial",
5707                   "vsetmaterial [-noupdate|-update] [name] MaterialName"
5708       "\n\t\t: Alias for vaspects -setmaterial [name] MaterialName.",
5709                   __FILE__,VAspects,group);
5710
5711   theCommands.Add("vunsetmaterial",
5712                   "vunsetmaterial [-noupdate|-update] [name]"
5713       "\n\t\t: Alias for vaspects -unsetmaterial [name].",
5714                   __FILE__,VAspects,group);
5715
5716   theCommands.Add("vsetwidth",
5717                   "vsetwidth [-noupdate|-update] [name] width(0->10)"
5718       "\n\t\t: Alias for vaspects -setwidth [name] width.",
5719                   __FILE__,VAspects,group);
5720
5721   theCommands.Add("vunsetwidth",
5722                   "vunsetwidth [-noupdate|-update] [name]"
5723       "\n\t\t: Alias for vaspects -unsetwidth [name] width.",
5724                   __FILE__,VAspects,group);
5725
5726   theCommands.Add("vsetinteriorstyle",
5727                   "vsetinteriorstyle [-noupdate|-update] [name] style"
5728       "\n\t\t: Where style is: 0 = EMPTY, 1 = HOLLOW, 2 = HATCH, 3 = SOLID, 4 = HIDDENLINE.",
5729                   __FILE__,VSetInteriorStyle,group);
5730
5731   theCommands.Add("vsensdis",
5732       "vsensdis : Display active entities (sensitive entities of one of the standard types corresponding to active selection modes)."
5733       "\n\t\t: Standard entity types are those defined in Select3D package:"
5734       "\n\t\t: - sensitive box"
5735       "\n\t\t: - sensitive face"
5736       "\n\t\t: - sensitive curve"
5737       "\n\t\t: - sensitive segment"
5738       "\n\t\t: - sensitive circle"
5739       "\n\t\t: - sensitive point"
5740       "\n\t\t: - sensitive triangulation"
5741       "\n\t\t: - sensitive triangle"
5742       "\n\t\t: Custom(application - defined) sensitive entity types are not processed by this command.",
5743       __FILE__,VDispSensi,group);
5744
5745   theCommands.Add("vsensera",
5746       "vsensera : erase active entities",
5747       __FILE__,VClearSensi,group);
5748
5749   theCommands.Add("vselprecision",
5750                   "vselprecision [-unset] [tolerance_value]"
5751                   "\n\t\t  Manages selection precision or prints current value if no parameter is passed."
5752                   "\n\t\t  -unset - restores default selection tolerance behavior, based on individual entity tolerance",
5753                   __FILE__,VSelPrecision,group);
5754
5755   theCommands.Add("vperf",
5756       "vperf: vperf  ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)"
5757       "\n\t\t: Tests the animation of an object along a predefined trajectory.",
5758       __FILE__,VPerf,group);
5759
5760   theCommands.Add("vanimation",
5761                   "vanimation CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile",
5762                   __FILE__,VAnimation,group);
5763
5764   theCommands.Add("vsetshading",
5765       "vsetshading  : vsetshading name Quality(default=0.0008) "
5766       "\n\t\t: Sets deflection coefficient that defines the quality of the shape representation in the shading mode.",
5767       __FILE__,VShading,group);
5768
5769   theCommands.Add("vunsetshading",
5770       "vunsetshading :vunsetshading name "
5771       "\n\t\t: Sets default deflection coefficient (0.0008) that defines the quality of the shape representation in the shading mode.",
5772       __FILE__,VShading,group);
5773
5774   theCommands.Add ("vtexture",
5775                    "\n'vtexture NameOfShape [TextureFile | IdOfTexture]\n"
5776                    "                         [-scale u v]  [-scale off]\n"
5777                    "                         [-origin u v] [-origin off]\n"
5778                    "                         [-repeat u v] [-repeat off]\n"
5779                    "                         [-modulate {on | off}]"
5780                    "                         [-default]'\n"
5781                    " The texture can be specified by filepath or as ID (0<=IdOfTexture<=20)\n"
5782                    " specifying one of the predefined textures.\n"
5783                    " The options are: \n"
5784                    "  -scale u v : enable texture scaling and set scale factors\n"
5785                    "  -scale off : disable texture scaling\n"
5786                    "  -origin u v : enable texture origin positioning and set the origin\n"
5787                    "  -origin off : disable texture origin positioning\n"
5788                    "  -repeat u v : enable texture repeat and set texture coordinate scaling\n"
5789                    "  -repeat off : disable texture repeat\n"
5790                    "  -modulate {on | off} : enable or disable texture modulation\n"
5791                    "  -default : sets texture mapping default parameters\n"
5792                    "or 'vtexture NameOfShape' if you want to disable texture mapping\n"
5793                    "or 'vtexture NameOfShape ?' to list available textures\n",
5794                     __FILE__, VTexture, group);
5795
5796   theCommands.Add("vtexscale",
5797                   "'vtexscale  NameOfShape ScaleU ScaleV' \n \
5798                    or 'vtexscale NameOfShape ScaleUV' \n \
5799                    or 'vtexscale NameOfShape' to disable scaling\n ",
5800                   __FILE__,VTexture,group);
5801
5802   theCommands.Add("vtexorigin",
5803                   "'vtexorigin NameOfShape UOrigin VOrigin' \n \
5804                    or 'vtexorigin NameOfShape UVOrigin' \n \
5805                    or 'vtexorigin NameOfShape' to disable origin positioning\n ",
5806                   __FILE__,VTexture,group);
5807
5808   theCommands.Add("vtexrepeat",
5809                   "'vtexrepeat  NameOfShape URepeat VRepeat' \n \
5810                    or 'vtexrepeat NameOfShape UVRepeat \n \
5811                    or 'vtexrepeat NameOfShape' to disable texture repeat \n ",
5812                   VTexture,group);
5813
5814   theCommands.Add("vtexdefault",
5815                   "'vtexdefault NameOfShape' to set texture mapping default parameters \n",
5816                   VTexture,group);
5817
5818   theCommands.Add("vsetam",
5819       "vsetam [shapename] mode"
5820       "\n\t\t: Activates selection mode for all selected or named shapes."
5821       "\n\t\t: Mod can be:"
5822       "\n\t\t:   0 - for shape itself" 
5823       "\n\t\t:   1 - vertices"
5824       "\n\t\t:   2 - edges"
5825       "\n\t\t:   3 - wires"
5826       "\n\t\t:   4 - faces"
5827       "\n\t\t:   5 - shells"
5828       "\n\t\t:   6 - solids"
5829       "\n\t\t:   7 - compounds"
5830       __FILE__,VActivatedMode,group);
5831
5832   theCommands.Add("vunsetam",
5833       "vunsetam : Deactivates all selection modes for all shapes.",
5834       __FILE__,VActivatedMode,group);
5835
5836   theCommands.Add("vstate",
5837       "vstate [-entities] [-hasSelected] [name1] ... [nameN]"
5838       "\n\t\t: Reports show/hidden state for selected or named objects"
5839       "\n\t\t:   -entities - print low-level information about detected entities"
5840       "\n\t\t:   -hasSelected - prints 1 if context has selected shape and 0 otherwise",
5841                   __FILE__,VState,group);
5842
5843   theCommands.Add("vpickshapes",
5844                   "vpickshape subtype(VERTEX,EDGE,WIRE,FACE,SHELL,SOLID) [name1 or .] [name2 or .] [name n or .]",
5845                   __FILE__,VPickShape,group);
5846
5847   theCommands.Add("vtypes",
5848                   "vtypes : list of known types and signatures in AIS - To be Used in vpickobject command for selection with filters",
5849                   VIOTypes,group);
5850
5851   theCommands.Add("vr",
5852       "vr filename"
5853       "\n\t\t: Reads shape from BREP-format file and displays it in the viewer. ",
5854                   __FILE__,vr, group);
5855
5856   theCommands.Add("vpickselected", "vpickselected [name]: extract selected shape.",
5857     __FILE__, VPickSelected, group);
5858
5859   theCommands.Add ("vloadselection",
5860     "vloadselection [-context] [name1] ... [nameN] : allows to load selection"
5861     "\n\t\t: primitives for the shapes with names given without displaying them."
5862     "\n\t\t:   -local - open local context before selection computation",
5863     __FILE__, VLoadSelection, group);
5864
5865   theCommands.Add ("vautoactivatesel",
5866     "vautoactivatesel [0|1] : manage or display the option to automatically"
5867     "\n\t\t: activate selection for newly displayed objects"
5868     "\n\t\t:   [0|1] - turn off | on auto activation of selection",
5869     __FILE__, VAutoActivateSelection, group);
5870
5871   theCommands.Add("vbsdf", "vbsdf [name] [options]"
5872     "\nAdjusts parameters of material BSDF:"
5873     "\n    -help : Shows this message"
5874     "\n    -print : Print BSDF"
5875     "\n    -kd : Weight of the Lambertian BRDF"
5876     "\n    -kr : Weight of the reflection BRDF"
5877     "\n    -kt : Weight of the transmission BTDF"
5878     "\n    -ks : Weight of the glossy Blinn BRDF"
5879     "\n    -le : Self-emitted radiance"
5880     "\n    -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
5881     "\n               Schlick x y z, Dielectric x, Conductor x y"
5882     "\n    -roughness : Roughness of material (Blinn's exponent)"
5883     "\n    -absorpcoeff : Absorption coefficient (only for transparent material)"
5884     "\n    -absorpcolor : Absorption color (only for transparent material)"
5885     "\n    -normalize : Normalize BSDF coefficients",
5886     __FILE__, VBsdf, group);
5887
5888 }
5889
5890 //=====================================================================
5891 //========================= for testing Draft and Rib =================
5892 //=====================================================================
5893 #include <BRepOffsetAPI_MakeThickSolid.hxx>
5894 #include <DBRep.hxx>
5895 #include <TopoDS_Face.hxx>
5896 #include <gp_Pln.hxx>
5897 #include <AIS_KindOfSurface.hxx>
5898 #include <BRepOffsetAPI_DraftAngle.hxx>
5899 #include <Precision.hxx>
5900 #include <BRepAlgo.hxx>
5901 #include <OSD_Environment.hxx>
5902 #include <DrawTrSurf.hxx>
5903 //#include <DbgTools.hxx>
5904 //#include <FeatAlgo_MakeLinearForm.hxx>
5905
5906
5907
5908
5909 //=======================================================================
5910 //function : IsValid
5911 //purpose  :
5912 //=======================================================================
5913 static Standard_Boolean IsValid(const TopTools_ListOfShape& theArgs,
5914                                 const TopoDS_Shape& theResult,
5915                                 const Standard_Boolean closedSolid,
5916                                 const Standard_Boolean GeomCtrl)
5917 {
5918   OSD_Environment check ("DONT_SWITCH_IS_VALID") ;
5919   TCollection_AsciiString checkValid = check.Value();
5920   Standard_Boolean ToCheck = Standard_True;
5921   if (!checkValid.IsEmpty()) {
5922 #ifdef OCCT_DEBUG
5923     cout <<"DONT_SWITCH_IS_VALID positionnee a :"<<checkValid.ToCString()<<"\n";
5924 #endif
5925     if ( checkValid=="true" || checkValid=="TRUE" ) {
5926       ToCheck= Standard_False;
5927     }
5928   } else {
5929 #ifdef OCCT_DEBUG
5930     cout <<"DONT_SWITCH_IS_VALID non positionne\n";
5931 #endif
5932   }
5933   Standard_Boolean IsValid = Standard_True;
5934   if (ToCheck)
5935     IsValid = BRepAlgo::IsValid(theArgs,theResult,closedSolid,GeomCtrl) ;
5936   return IsValid;
5937
5938 }
5939
5940 //===============================================================================
5941 // TDraft : test draft, uses AIS Viewer
5942 // Solid Face Plane Angle  Reverse
5943 //===============================================================================
5944 static Standard_Integer TDraft(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5945 {
5946   if (argc < 5) return 1;
5947 // argv[1] - TopoDS_Shape Solid
5948 // argv[2] - TopoDS_Shape Face
5949 // argv[3] - TopoDS_Shape Plane
5950 // argv[4] - Standard_Real Angle
5951 // argv[5] - Standard_Integer Reverse
5952
5953 //  Sprintf(prefix, argv[1]);
5954   Standard_Real anAngle = 0;
5955   Standard_Boolean Rev = Standard_False;
5956   Standard_Integer rev = 0;
5957   TopoDS_Shape Solid  = GetShapeFromName(argv[1]);
5958   TopoDS_Shape face   = GetShapeFromName(argv[2]);
5959   TopoDS_Face Face    = TopoDS::Face(face);
5960   TopoDS_Shape Plane  = GetShapeFromName(argv[3]);
5961   if (Plane.IsNull ()) {
5962     di << "TEST : Plane is NULL\n";
5963     return 1;
5964   }
5965   anAngle = Draw::Atof(argv[4]);
5966   anAngle = 2*M_PI * anAngle / 360.0;
5967   gp_Pln aPln;
5968   Handle( Geom_Surface )aSurf;
5969   AIS_KindOfSurface aSurfType;
5970   Standard_Real Offset;
5971   gp_Dir aDir;
5972   if(argc > 4) { // == 5
5973     rev = Draw::Atoi(argv[5]);
5974     Rev = (rev)? Standard_True : Standard_False;
5975   }
5976
5977   TopoDS_Face face2 = TopoDS::Face(Plane);
5978   if(!AIS::GetPlaneFromFace(face2, aPln, aSurf, aSurfType, Offset))
5979     {
5980       di << "TEST : Can't find plane\n";
5981       return 1;
5982     }
5983
5984   aDir = aPln.Axis().Direction();
5985   if (!aPln.Direct())
5986     aDir.Reverse();
5987   if (Plane.Orientation() == TopAbs_REVERSED)
5988     aDir.Reverse();
5989   di << "TEST : gp::Resolution() = " << gp::Resolution() << "\n";
5990
5991   BRepOffsetAPI_DraftAngle Draft (Solid);
5992
5993   if(Abs(anAngle)< Precision::Angular()) {
5994     di << "TEST : NULL angle\n";
5995     return 1;}
5996
5997   if(Rev) anAngle = - anAngle;
5998   Draft.Add (Face, aDir, anAngle, aPln);
5999   Draft.Build ();
6000   if (!Draft.IsDone())  {
6001     di << "TEST : Draft Not DONE \n";
6002     return 1;
6003   }
6004   TopTools_ListOfShape Larg;
6005   Larg.Append(Solid);
6006   if (!IsValid(Larg,Draft.Shape(),Standard_True,Standard_False)) {
6007     di << "TEST : DesignAlgo returns Not valid\n";
6008     return 1;
6009   }
6010
6011   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
6012   Handle(AIS_Shape) ais = new AIS_Shape(Draft.Shape());
6013
6014   if ( !ais.IsNull() ) {
6015     ais->SetColor(DEFAULT_COLOR);
6016     ais->SetMaterial(DEFAULT_MATERIAL);
6017     // Display the AIS_Shape without redraw
6018     Ctx->Display(ais, Standard_False);
6019
6020     const char *Name = "draft1";
6021     Standard_Boolean IsBound = GetMapOfAIS().IsBound2(Name);
6022     if (IsBound) {
6023       Handle(AIS_InteractiveObject) an_object =
6024         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(Name));
6025       if (!an_object.IsNull()) {
6026         Ctx->Remove(an_object,
6027                     Standard_True) ;
6028         GetMapOfAIS().UnBind2(Name) ;
6029       }
6030     }
6031     GetMapOfAIS().Bind(ais, Name);
6032 //  DBRep::Set("draft", ais->Shape());
6033   }
6034   Ctx->Display(ais, Standard_True);
6035   return 0;
6036 }
6037
6038 //==============================================================================
6039 //function : splitParameter
6040 //purpose  : Split parameter string to parameter name and parameter value
6041 //==============================================================================
6042 Standard_Boolean ViewerTest::SplitParameter (const TCollection_AsciiString& theString,
6043                                              TCollection_AsciiString&       theName,
6044                                              TCollection_AsciiString&       theValue)
6045 {
6046   Standard_Integer aParamNameEnd = theString.FirstLocationInSet ("=", 1, theString.Length());
6047
6048   if (aParamNameEnd == 0)
6049   {
6050     return Standard_False;
6051   }
6052
6053   TCollection_AsciiString aString (theString);
6054   if (aParamNameEnd != 0)
6055   {
6056     theValue = aString.Split (aParamNameEnd);
6057     aString.Split (aString.Length() - 1);
6058     theName = aString;
6059   }
6060
6061   return Standard_True;
6062 }
6063
6064 //============================================================================
6065 //  MyCommands
6066 //============================================================================
6067 void ViewerTest::MyCommands( Draw_Interpretor& theCommands)
6068 {
6069
6070   DrawTrSurf::BasicCommands(theCommands);
6071   const char* group = "Check Features Operations commands";
6072
6073   theCommands.Add("Draft","Draft    Solid Face Plane Angle Reverse",
6074                   __FILE__,
6075                   &TDraft,group); //Draft_Modification
6076 }
6077
6078 //==============================================================================
6079 // ViewerTest::Factory
6080 //==============================================================================
6081 void ViewerTest::Factory(Draw_Interpretor& theDI)
6082 {
6083   // definition of Viewer Command
6084   ViewerTest::Commands(theDI);
6085   ViewerTest::AviCommands(theDI);
6086
6087 #ifdef OCCT_DEBUG
6088       theDI << "Draw Plugin : OCC V2d & V3d commands are loaded\n";
6089 #endif
6090 }
6091
6092 // Declare entry point PLUGINFACTORY
6093 DPLUGIN(ViewerTest)