96bcd5fa164077314477e889f637e6b7b954f19a
[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     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2780          anIter.More(); anIter.Next())
2781     {
2782       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2783       if (!anIO.IsNull()
2784        && aCtx->IsSelected (anIO))
2785       {
2786         theDI << anIter.Key2().ToCString() << " ";
2787         if (toEraseInView)
2788         {
2789           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2790         }
2791         else
2792         {
2793           aCtx->Erase (anIO, Standard_False);
2794         }
2795       }
2796     }
2797   }
2798   else
2799   {
2800     // Erase all objects
2801     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2802          anIter.More(); anIter.Next())
2803     {
2804       const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2805       if (!anIO.IsNull())
2806       {
2807         if (toEraseInView)
2808         {
2809           aCtx->SetViewAffinity (anIO, aView, Standard_False);
2810         }
2811         else
2812         {
2813           aCtx->Erase (anIO, Standard_False);
2814         }
2815       }
2816     }
2817   }
2818
2819   return 0;
2820 }
2821
2822 //==============================================================================
2823 //function : VDisplayAll
2824 //author   : ege
2825 //purpose  : Display all the objects of the Map
2826 //==============================================================================
2827 static int VDisplayAll (Draw_Interpretor& ,
2828                         Standard_Integer  theArgNb,
2829                         const char**      theArgVec)
2830
2831 {
2832   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2833   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2834   if (aCtx.IsNull())
2835   {
2836     std::cerr << "Error: no active view!\n";
2837     return 1;
2838   }
2839
2840   Standard_Integer anArgIter = 1;
2841   Standard_Boolean toDisplayLocal = Standard_False;
2842   for (; anArgIter < theArgNb; ++anArgIter)
2843   {
2844     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2845     anArgCase.LowerCase();
2846     if (anArgCase == "-local")
2847     {
2848       toDisplayLocal = Standard_True;
2849     }
2850     else if (anUpdateTool.parseRedrawMode (anArgCase))
2851     {
2852       continue;
2853     }
2854     else
2855     {
2856       break;
2857     }
2858   }
2859   if (anArgIter < theArgNb)
2860   {
2861     std::cout << theArgVec[0] << "Error: wrong syntax\n";
2862     return 1;
2863   }
2864
2865   if (toDisplayLocal && !aCtx->HasOpenedContext())
2866   {
2867     std::cerr << "Error: local selection context is not open.\n";
2868     return 1;
2869   }
2870   else if (!toDisplayLocal && aCtx->HasOpenedContext())
2871   {
2872     aCtx->CloseLocalContext (Standard_False);
2873   }
2874
2875   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2876        anIter.More(); anIter.Next())
2877   {
2878     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2879     aCtx->Erase (aShape, Standard_False);
2880   }
2881
2882   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
2883        anIter.More(); anIter.Next())
2884   {
2885     const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
2886     aCtx->Display (aShape, Standard_False);
2887   }
2888   return 0;
2889 }
2890
2891 //! Auxiliary method to find presentation
2892 inline Handle(PrsMgr_Presentation) findPresentation (const Handle(AIS_InteractiveContext)& theCtx,
2893                                                      const Handle(AIS_InteractiveObject)&  theIO,
2894                                                      const Standard_Integer                theMode)
2895 {
2896   if (theIO.IsNull())
2897   {
2898     return Handle(PrsMgr_Presentation)();
2899   }
2900
2901   if (theMode != -1)
2902   {
2903     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
2904     {
2905       return theCtx->MainPrsMgr()->Presentation (theIO, theMode);
2906     }
2907   }
2908   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
2909   {
2910     return theCtx->MainPrsMgr()->Presentation (theIO, theIO->DisplayMode());
2911   }
2912   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
2913   {
2914     return theCtx->MainPrsMgr()->Presentation (theIO, theCtx->DisplayMode());
2915   }
2916   return Handle(PrsMgr_Presentation)();
2917 }
2918
2919 enum ViewerTest_BndAction
2920 {
2921   BndAction_Hide,
2922   BndAction_Show,
2923   BndAction_Print
2924 };
2925
2926 //! Auxiliary method to print bounding box of presentation
2927 inline void bndPresentation (Draw_Interpretor&                  theDI,
2928                              const Handle(PrsMgr_Presentation)& thePrs,
2929                              const TCollection_AsciiString&     theName,
2930                              const ViewerTest_BndAction         theAction)
2931 {
2932   switch (theAction)
2933   {
2934     case BndAction_Hide:
2935     {
2936       thePrs->Presentation()->GraphicUnHighlight();
2937       break;
2938     }
2939     case BndAction_Show:
2940     {
2941       Handle(Graphic3d_Structure) aPrs (thePrs->Presentation());
2942       aPrs->CStructure()->HighlightColor.r = 0.988235f;
2943       aPrs->CStructure()->HighlightColor.g = 0.988235f;
2944       aPrs->CStructure()->HighlightColor.b = 0.988235f;
2945       aPrs->CStructure()->HighlightWithBndBox (aPrs, Standard_True);
2946       break;
2947     }
2948     case BndAction_Print:
2949     {
2950       Bnd_Box aBox = thePrs->Presentation()->MinMaxValues();
2951       gp_Pnt aMin = aBox.CornerMin();
2952       gp_Pnt aMax = aBox.CornerMax();
2953       theDI << theName  << "\n"
2954             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
2955             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
2956       break;
2957     }
2958   }
2959 }
2960
2961 //==============================================================================
2962 //function : VBounding
2963 //purpose  :
2964 //==============================================================================
2965 int VBounding (Draw_Interpretor& theDI,
2966                Standard_Integer  theArgNb,
2967                const char**      theArgVec)
2968 {
2969   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2970   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2971   if (aCtx.IsNull())
2972   {
2973     std::cout << "Error: no active view!\n";
2974     return 1;
2975   }
2976
2977   ViewerTest_BndAction anAction = BndAction_Show;
2978   Standard_Integer     aMode    = -1;
2979
2980   Standard_Integer anArgIter = 1;
2981   for (; anArgIter < theArgNb; ++anArgIter)
2982   {
2983     TCollection_AsciiString anArg (theArgVec[anArgIter]);
2984     anArg.LowerCase();
2985     if (anArg == "-print")
2986     {
2987       anAction = BndAction_Print;
2988     }
2989     else if (anArg == "-show")
2990     {
2991       anAction = BndAction_Show;
2992     }
2993     else if (anArg == "-hide")
2994     {
2995       anAction = BndAction_Hide;
2996     }
2997     else if (anArg == "-mode")
2998     {
2999       if (++anArgIter >= theArgNb)
3000       {
3001         std::cout << "Error: wrong syntax at " << anArg << "\n";
3002         return 1;
3003       }
3004       aMode = Draw::Atoi (theArgVec[anArgIter]);
3005     }
3006     else if (!anUpdateTool.parseRedrawMode (anArg))
3007     {
3008       break;
3009     }
3010   }
3011
3012   if (anArgIter < theArgNb)
3013   {
3014     // has a list of names
3015     for (; anArgIter < theArgNb; ++anArgIter)
3016     {
3017       TCollection_AsciiString aName = theArgVec[anArgIter];
3018       if (!GetMapOfAIS().IsBound2 (aName))
3019       {
3020         std::cout << "Error: presentation " << aName << " does not exist\n";
3021         return 1;
3022       }
3023
3024       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
3025       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3026       if (aPrs.IsNull())
3027       {
3028         std::cout << "Error: presentation " << aName << " does not exist\n";
3029         return 1;
3030       }
3031       bndPresentation (theDI, aPrs, aName, anAction);
3032     }
3033   }
3034   else if (aCtx->NbSelected() > 0)
3035   {
3036     // remove all currently selected objects
3037     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3038     {
3039       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
3040       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3041       if (!aPrs.IsNull())
3042       {
3043         bndPresentation (theDI, aPrs, GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction);
3044       }
3045     }
3046   }
3047   else
3048   {
3049     // all objects
3050     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3051          anIter.More(); anIter.Next())
3052     {
3053       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1());
3054       Handle(PrsMgr_Presentation)   aPrs = findPresentation (aCtx, anIO, aMode);
3055       if (!aPrs.IsNull())
3056       {
3057         bndPresentation (theDI, aPrs, anIter.Key2(), anAction);
3058       }
3059     }
3060   }
3061   return 0;
3062 }
3063
3064 //==============================================================================
3065 //function : VTexture
3066 //purpose  :
3067 //==============================================================================
3068 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgv)
3069 {
3070   TCollection_AsciiString aCommandName (theArgv[0]);
3071
3072   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
3073   if (aCommandName == "vtexture")
3074   {
3075     if (theArgsNb < 2)
3076     {
3077       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
3078       std::cout << "Type help for more information.\n";
3079       return 1;
3080     }
3081
3082     // look for options of vtexture command
3083     TCollection_AsciiString aParseKey;
3084     for (Standard_Integer anArgIt = 2; anArgIt < theArgsNb; ++anArgIt)
3085     {
3086       TCollection_AsciiString anArg (theArgv [anArgIt]);
3087
3088       anArg.UpperCase();
3089       if (anArg.Value (1) == '-' && !anArg.IsRealValue())
3090       {
3091         aParseKey = anArg;
3092         aParseKey.Remove (1);
3093         aParseKey.UpperCase();
3094         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
3095         continue;
3096       }
3097
3098       if (aParseKey.IsEmpty())
3099       {
3100         continue;
3101       }
3102
3103       aMapOfArgs(aParseKey)->Append (anArg);
3104     }
3105   }
3106   else if (aCommandName == "vtexscale"
3107         || aCommandName == "vtexorigin"
3108         || aCommandName == "vtexrepeat")
3109   {
3110     // scan for parameters of vtexscale, vtexorigin, vtexrepeat commands
3111     // equal to -scale, -origin, -repeat options of vtexture command
3112     if (theArgsNb < 2 || theArgsNb > 4)
3113     {
3114       std::cout << theArgv[0] << ": " << " invalid arguments.\n";
3115       std::cout << "Type help for more information.\n";
3116       return 1;
3117     }
3118
3119     Handle(TColStd_HSequenceOfAsciiString) anArgs = new TColStd_HSequenceOfAsciiString;
3120     if (theArgsNb == 2)
3121     {
3122       anArgs->Append ("OFF");
3123     }
3124     else if (theArgsNb == 4)
3125     {
3126       anArgs->Append (TCollection_AsciiString (theArgv[2]));
3127       anArgs->Append (TCollection_AsciiString (theArgv[3]));
3128     }
3129
3130     TCollection_AsciiString anArgKey;
3131     if (aCommandName == "vtexscale")
3132     {
3133       anArgKey = "SCALE";
3134     }
3135     else if (aCommandName == "vtexorigin")
3136     {
3137       anArgKey = "ORIGIN";
3138     }
3139     else
3140     {
3141       anArgKey = "REPEAT";
3142     }
3143
3144     aMapOfArgs.Bind (anArgKey, anArgs);
3145   }
3146   else if (aCommandName == "vtexdefault")
3147   {
3148     // scan for parameters of vtexdefault command
3149     // equal to -default option of vtexture command
3150     aMapOfArgs.Bind ("DEFAULT", new TColStd_HSequenceOfAsciiString);
3151   }
3152
3153   // Check arguments for validity
3154   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
3155   for (; aMapIt.More(); aMapIt.Next())
3156   {
3157     const TCollection_AsciiString& aKey = aMapIt.Key();
3158     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
3159
3160     // -scale, -origin, -repeat: one argument "off", or two real values
3161     if ((aKey.IsEqual ("SCALE") || aKey.IsEqual ("ORIGIN") || aKey.IsEqual ("REPEAT"))
3162       && ((anArgs->Length() == 1 && anArgs->Value(1) == "OFF")
3163        || (anArgs->Length() == 2 && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue())))
3164     {
3165       continue;
3166     }
3167
3168     // -modulate: single argument "on" / "off"
3169     if (aKey.IsEqual ("MODULATE") && anArgs->Length() == 1 && (anArgs->Value(1) == "OFF" || anArgs->Value(1) == "ON"))
3170     {
3171       continue;
3172     }
3173
3174     // -default: no arguments
3175     if (aKey.IsEqual ("DEFAULT") && anArgs->IsEmpty())
3176     {
3177       continue;
3178     }
3179
3180     TCollection_AsciiString aLowerKey;
3181     aLowerKey  = "-";
3182     aLowerKey += aKey;
3183     aLowerKey.LowerCase();
3184     std::cout << theArgv[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
3185     std::cout << "Type help for more information.\n";
3186     return 1;
3187   }
3188
3189   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3190   if (anAISContext.IsNull())
3191   {
3192     std::cout << aCommandName << ": " << " please use 'vinit' command to initialize view.\n";
3193     return 1;
3194   }
3195
3196   Standard_Integer aPreviousMode = 0;
3197
3198   ViewerTest::CurrentView()->SetSurfaceDetail (V3d_TEX_ALL);
3199
3200   TCollection_AsciiString aShapeName (theArgv[1]);
3201   Handle(AIS_InteractiveObject) anIO;
3202
3203   const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
3204   if (aMapOfIO.IsBound2 (aShapeName))
3205   {
3206     anIO = Handle(AIS_InteractiveObject)::DownCast (aMapOfIO.Find2 (aShapeName));
3207   }
3208
3209   if (anIO.IsNull())
3210   {
3211     std::cout << aCommandName << ": shape " << aShapeName << " does not exists.\n";
3212     return 1;
3213   }
3214
3215   Handle(AIS_TexturedShape) aTexturedIO;
3216   if (anIO->IsKind (STANDARD_TYPE (AIS_TexturedShape)))
3217   {
3218     aTexturedIO = Handle(AIS_TexturedShape)::DownCast (anIO);
3219     aPreviousMode = aTexturedIO->DisplayMode();
3220   }
3221   else
3222   {
3223     anAISContext->Remove (anIO, Standard_False);
3224     aTexturedIO = new AIS_TexturedShape (DBRep::Get (theArgv[1]));
3225     GetMapOfAIS().UnBind1 (anIO);
3226     GetMapOfAIS().UnBind2 (aShapeName);
3227     GetMapOfAIS().Bind (aTexturedIO, aShapeName);
3228   }
3229
3230   // -------------------------------------------
3231   //  Turn texturing on/off - only for vtexture
3232   // -------------------------------------------
3233
3234   if (aCommandName == "vtexture")
3235   {
3236     TCollection_AsciiString aTextureArg (theArgsNb > 2 ? theArgv[2] : "");
3237
3238     if (aTextureArg.IsEmpty())
3239     {
3240       std::cout << aCommandName << ": " << " Texture mapping disabled.\n";
3241       std::cout << "To enable it, use 'vtexture NameOfShape NameOfTexture'\n" << "\n";
3242
3243       anAISContext->SetDisplayMode (aTexturedIO, AIS_Shaded, Standard_False);
3244       if (aPreviousMode == 3)
3245       {
3246         anAISContext->RecomputePrsOnly (aTexturedIO);
3247       }
3248
3249       anAISContext->Display (aTexturedIO, Standard_True);
3250       return 0;
3251     }
3252     else if (aTextureArg.Value(1) != '-') // "-option" on place of texture argument
3253     {
3254       if (aTextureArg == "?")
3255       {
3256         TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
3257
3258         theDi << "\n Files in current directory : \n" << "\n";
3259         theDi.Eval ("glob -nocomplain *");
3260
3261         TCollection_AsciiString aCmnd ("glob -nocomplain ");
3262         aCmnd += aTextureFolder;
3263         aCmnd += "/* ";
3264
3265         theDi << "Files in " << aTextureFolder.ToCString() << " : \n" << "\n";
3266         theDi.Eval (aCmnd.ToCString());
3267         return 0;
3268       }
3269       else
3270       {
3271         aTexturedIO->SetTextureFileName (aTextureArg);
3272       }
3273     }
3274   }
3275
3276   // ------------------------------------
3277   //  Process other options and commands
3278   // ------------------------------------
3279
3280   Handle(TColStd_HSequenceOfAsciiString) aValues;
3281   if (aMapOfArgs.Find ("DEFAULT", aValues))
3282   {
3283     aTexturedIO->SetTextureRepeat (Standard_False);
3284     aTexturedIO->SetTextureOrigin (Standard_False);
3285     aTexturedIO->SetTextureScale  (Standard_False);
3286     aTexturedIO->EnableTextureModulate();
3287   }
3288   else
3289   {
3290     if (aMapOfArgs.Find ("SCALE", aValues))
3291     {
3292       if (aValues->Value(1) != "OFF")
3293       {
3294         aTexturedIO->SetTextureScale (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3295       }
3296       else
3297       {
3298         aTexturedIO->SetTextureScale (Standard_False);
3299       }
3300     }
3301
3302     if (aMapOfArgs.Find ("ORIGIN", aValues))
3303     {
3304       if (aValues->Value(1) != "OFF")
3305       {
3306         aTexturedIO->SetTextureOrigin (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3307       }
3308       else
3309       {
3310         aTexturedIO->SetTextureOrigin (Standard_False);
3311       }
3312     }
3313
3314     if (aMapOfArgs.Find ("REPEAT", aValues))
3315     {
3316       if (aValues->Value(1) != "OFF")
3317       {
3318         aTexturedIO->SetTextureRepeat (Standard_True, aValues->Value(1).RealValue(), aValues->Value(2).RealValue());
3319       }
3320       else
3321       {
3322         aTexturedIO->SetTextureRepeat (Standard_False);
3323       }
3324     }
3325
3326     if (aMapOfArgs.Find ("MODULATE", aValues))
3327     {
3328       if (aValues->Value(1) == "ON")
3329       {
3330         aTexturedIO->EnableTextureModulate();
3331       }
3332       else
3333       {
3334         aTexturedIO->DisableTextureModulate();
3335       }
3336     }
3337   }
3338
3339   if (aTexturedIO->DisplayMode() == 3 || aPreviousMode == 3)
3340   {
3341     anAISContext->RecomputePrsOnly (aTexturedIO);
3342   }
3343   else
3344   {
3345     anAISContext->SetDisplayMode (aTexturedIO, 3, Standard_False);
3346     anAISContext->Display (aTexturedIO, Standard_True);
3347     anAISContext->Update (aTexturedIO,Standard_True);
3348   }
3349
3350   return 0;
3351 }
3352
3353 //! Auxiliary method to parse transformation persistence flags
3354 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
3355                                            Standard_Integer&              theFlags)
3356 {
3357   if (theFlagString == "pan")
3358   {
3359     theFlags |= Graphic3d_TMF_PanPers;
3360   }
3361   else if (theFlagString == "zoom")
3362   {
3363     theFlags |= Graphic3d_TMF_ZoomPers;
3364   }
3365   else if (theFlagString == "rotate")
3366   {
3367     theFlags |= Graphic3d_TMF_RotatePers;
3368   }
3369   else if (theFlagString == "trihedron")
3370   {
3371     theFlags = Graphic3d_TMF_TriedronPers;
3372   }
3373   else if (theFlagString == "full")
3374   {
3375     theFlags = Graphic3d_TMF_FullPers;
3376   }
3377   else if (theFlagString == "none")
3378   {
3379     theFlags = Graphic3d_TMF_None;
3380   }
3381   else
3382   {
3383     return Standard_False;
3384   }
3385
3386   return Standard_True;
3387 }
3388
3389 //==============================================================================
3390 //function : VDisplay2
3391 //author   : ege
3392 //purpose  : Display an object from its name
3393 //==============================================================================
3394 static int VDisplay2 (Draw_Interpretor& theDI,
3395                       Standard_Integer  theArgNb,
3396                       const char**      theArgVec)
3397 {
3398   if (theArgNb < 2)
3399   {
3400     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
3401     return 1;
3402   }
3403
3404   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3405   if (aCtx.IsNull())
3406   {
3407     ViewerTest::ViewerInit();
3408     aCtx = ViewerTest::GetAISContext();
3409   }
3410
3411   // Parse input arguments
3412   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3413   Standard_Integer   isMutable      = -1;
3414   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
3415   Standard_Boolean   toDisplayLocal = Standard_False;
3416   Standard_Boolean   toReDisplay    = Standard_False;
3417   Standard_Integer   isSelectable   = -1;
3418   Standard_Integer   anObjDispMode  = -2;
3419   Standard_Integer   anObjHighMode  = -2;
3420   Standard_Boolean   toSetTrsfPers  = Standard_False;
3421   Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
3422   gp_Pnt aTPPosition;
3423   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
3424   AIS_DisplayStatus aDispStatus = AIS_DS_None;
3425   Standard_Integer toDisplayInView = Standard_False;
3426   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3427   {
3428     const TCollection_AsciiString aName     = theArgVec[anArgIter];
3429     TCollection_AsciiString       aNameCase = aName;
3430     aNameCase.LowerCase();
3431     if (anUpdateTool.parseRedrawMode (aName))
3432     {
3433       continue;
3434     }
3435     else if (aNameCase == "-mutable")
3436     {
3437       isMutable = 1;
3438     }
3439     else if (aNameCase == "-neutral")
3440     {
3441       aDispStatus = AIS_DS_Displayed;
3442     }
3443     else if (aNameCase == "-immediate"
3444           || aNameCase == "-top")
3445     {
3446       aZLayer = Graphic3d_ZLayerId_Top;
3447     }
3448     else if (aNameCase == "-topmost")
3449     {
3450       aZLayer = Graphic3d_ZLayerId_Topmost;
3451     }
3452     else if (aNameCase == "-osd"
3453           || aNameCase == "-toposd"
3454           || aNameCase == "-overlay")
3455     {
3456       aZLayer = Graphic3d_ZLayerId_TopOSD;
3457     }
3458     else if (aNameCase == "-botosd"
3459           || aNameCase == "-underlay")
3460     {
3461       aZLayer = Graphic3d_ZLayerId_BotOSD;
3462     }
3463     else if (aNameCase == "-select"
3464           || aNameCase == "-selectable")
3465     {
3466       isSelectable = 1;
3467     }
3468     else if (aNameCase == "-noselect"
3469           || aNameCase == "-noselection")
3470     {
3471       isSelectable = 0;
3472     }
3473     else if (aNameCase == "-dispmode"
3474           || aNameCase == "-displaymode")
3475     {
3476       if (++anArgIter >= theArgNb)
3477       {
3478         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3479         return 1;
3480       }
3481
3482       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
3483     }
3484     else if (aNameCase == "-highmode"
3485           || aNameCase == "-highlightmode")
3486     {
3487       if (++anArgIter >= theArgNb)
3488       {
3489         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3490         return 1;
3491       }
3492
3493       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
3494     }
3495     else if (aNameCase == "-3d")
3496     {
3497       toSetTrsfPers  = Standard_True;
3498       aTrsfPersFlags = Graphic3d_TMF_None;
3499     }
3500     else if (aNameCase == "-2d")
3501     {
3502       toSetTrsfPers  = Standard_True;
3503       aTrsfPersFlags = Graphic3d_TMF_2d;
3504     }
3505     else if (aNameCase == "-2dtopdown")
3506     {
3507       toSetTrsfPers  = Standard_True;
3508       aTrsfPersFlags = Graphic3d_TMF_2d | Graphic3d_TMF_2d_IsTopDown;
3509     }
3510     else if (aNameCase == "-trsfpers"
3511           || aNameCase == "-pers")
3512     {
3513       if (++anArgIter >= theArgNb)
3514       {
3515         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3516         return 1;
3517       }
3518
3519       toSetTrsfPers  = Standard_True;
3520       aTrsfPersFlags = Graphic3d_TMF_None;
3521       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
3522       aPersFlags.LowerCase();
3523       for (Standard_Integer aParserPos = aPersFlags.Search ("|");; aParserPos = aPersFlags.Search ("|"))
3524       {
3525         if (aParserPos == -1)
3526         {
3527           if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
3528           {
3529             std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
3530             return 1;
3531           }
3532           break;
3533         }
3534
3535         TCollection_AsciiString anOtherFlags = aPersFlags.Split (aParserPos - 1);
3536         if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
3537         {
3538           std::cerr << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".\n";
3539           return 1;
3540         }
3541         aPersFlags = anOtherFlags;
3542       }
3543     }
3544     else if (aNameCase == "-trsfperspos"
3545           || aNameCase == "-perspos")
3546     {
3547       if (anArgIter + 2 >= theArgNb)
3548       {
3549         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3550         return 1;
3551       }
3552
3553       TCollection_AsciiString aX (theArgVec[++anArgIter]);
3554       TCollection_AsciiString aY (theArgVec[++anArgIter]);
3555       TCollection_AsciiString aZ = "0";
3556       if (!aX.IsIntegerValue()
3557        || !aY.IsIntegerValue())
3558       {
3559         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3560         return 1;
3561       }
3562       if (anArgIter + 1 < theArgNb)
3563       {
3564         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
3565         if (aTemp.IsIntegerValue())
3566         {
3567           aZ = aTemp;
3568           ++anArgIter;
3569         }
3570       }
3571       aTPPosition.SetCoord (aX.IntegerValue(), aY.IntegerValue(), aZ.IntegerValue());
3572     }
3573     else if (aNameCase == "-layer")
3574     {
3575       if (++anArgIter >= theArgNb)
3576       {
3577         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3578         return 1;
3579       }
3580
3581       TCollection_AsciiString aValue (theArgVec[anArgIter]);
3582       if (!aValue.IsIntegerValue())
3583       {
3584         std::cerr << "Error: wrong syntax at " << aName << ".\n";
3585         return 1;
3586       }
3587
3588       aZLayer = aValue.IntegerValue();
3589     }
3590     else if (aNameCase == "-view"
3591           || aNameCase == "-inview")
3592     {
3593       toDisplayInView = Standard_True;
3594     }
3595     else if (aNameCase == "-local")
3596     {
3597       aDispStatus = AIS_DS_Temporary;
3598       toDisplayLocal = Standard_True;
3599     }
3600     else if (aNameCase == "-redisplay")
3601     {
3602       toReDisplay = Standard_True;
3603     }
3604     else
3605     {
3606       aNamesOfDisplayIO.Append (aName);
3607     }
3608   }
3609
3610   if (aNamesOfDisplayIO.IsEmpty())
3611   {
3612     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
3613     return 1;
3614   }
3615
3616   // Prepare context for display
3617   if (toDisplayLocal && !aCtx->HasOpenedContext())
3618   {
3619     aCtx->OpenLocalContext (Standard_False);
3620   }
3621   else if (!toDisplayLocal && aCtx->HasOpenedContext())
3622   {
3623     aCtx->CloseAllContexts (Standard_False);
3624   }
3625
3626   // Display interactive objects
3627   for (Standard_Integer anIter = 1; anIter <= aNamesOfDisplayIO.Length(); ++anIter)
3628   {
3629     const TCollection_AsciiString& aName = aNamesOfDisplayIO.Value(anIter);
3630
3631     if (!GetMapOfAIS().IsBound2 (aName))
3632     {
3633       // create the AIS_Shape from a name
3634       const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
3635       if (!aShape.IsNull())
3636       {
3637         if (isMutable != -1)
3638         {
3639           aShape->SetMutable (isMutable == 1);
3640         }
3641         if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
3642         {
3643           aShape->SetZLayer (aZLayer);
3644         }
3645         if (toSetTrsfPers)
3646         {
3647           aShape->SetTransformPersistence (aTrsfPersFlags, aTPPosition);
3648         }
3649         if (anObjDispMode != -2)
3650         {
3651           aShape->SetDisplayMode (anObjDispMode);
3652         }
3653         if (anObjHighMode != -2)
3654         {
3655           aShape->SetHilightMode (anObjHighMode);
3656         }
3657         if (!toDisplayLocal)
3658           GetMapOfAIS().Bind (aShape, aName);
3659
3660         Standard_Integer aDispMode = aShape->HasDisplayMode()
3661                                    ? aShape->DisplayMode()
3662                                    : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
3663                                     ? aCtx->DisplayMode()
3664                                     : 0);
3665         Standard_Integer aSelMode = -1;
3666         if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
3667         {
3668           aSelMode = aShape->GlobalSelectionMode();
3669         }
3670
3671         aCtx->Display (aShape, aDispMode, aSelMode,
3672                        Standard_False, aShape->AcceptShapeDecomposition(),
3673                        aDispStatus);
3674         if (toDisplayInView)
3675         {
3676           for (aCtx->CurrentViewer()->InitDefinedViews(); aCtx->CurrentViewer()->MoreDefinedViews(); aCtx->CurrentViewer()->NextDefinedViews())
3677           {
3678             aCtx->SetViewAffinity (aShape, aCtx->CurrentViewer()->DefinedView(), Standard_False);
3679           }
3680           aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
3681         }
3682       }
3683       else
3684       {
3685         std::cerr << "Error: object with name '" << aName << "' does not exist!\n";
3686       }
3687       continue;
3688     }
3689
3690     Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
3691     if (isMutable != -1)
3692     {
3693       aShape->SetMutable (isMutable == 1);
3694     }
3695     if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
3696     {
3697       aShape->SetZLayer (aZLayer);
3698     }
3699     if (toSetTrsfPers)
3700     {
3701       aShape->SetTransformPersistence (aTrsfPersFlags, aTPPosition);
3702     }
3703     if (anObjDispMode != -2)
3704     {
3705       aShape->SetDisplayMode (anObjDispMode);
3706     }
3707     if (anObjHighMode != -2)
3708     {
3709       aShape->SetHilightMode (anObjHighMode);
3710     }
3711     Standard_Integer aDispMode = aShape->HasDisplayMode()
3712                                 ? aShape->DisplayMode()
3713                                 : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
3714                                 ? aCtx->DisplayMode()
3715                                 : 0);
3716     Standard_Integer aSelMode = -1;
3717     if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
3718     {
3719       aSelMode = aShape->GlobalSelectionMode();
3720     }
3721
3722     if (aShape->Type() == AIS_KOI_Datum)
3723     {
3724       aCtx->Display (aShape, Standard_False);
3725     }
3726     else
3727     {
3728       theDI << "Display " << aName.ToCString() << "\n";
3729
3730       // update the Shape in the AIS_Shape
3731       TopoDS_Shape      aNewShape = GetShapeFromName (aName.ToCString());
3732       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
3733       if (!aShapePrs.IsNull())
3734       {
3735         if (!aShapePrs->Shape().IsEqual (aNewShape))
3736         {
3737           toReDisplay = Standard_True;
3738         }
3739         aShapePrs->Set (aNewShape);
3740       }
3741       if (toReDisplay)
3742       {
3743         aCtx->Redisplay (aShape, Standard_False);
3744       }
3745
3746       if (aSelMode == -1)
3747       {
3748         aCtx->Erase (aShape);
3749       }
3750       aCtx->Display (aShape, aDispMode, aSelMode,
3751                      Standard_False, aShape->AcceptShapeDecomposition(),
3752                      aDispStatus);
3753       if (toDisplayInView)
3754       {
3755         aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
3756       }
3757     }
3758   }
3759
3760   return 0;
3761 }
3762
3763 //===============================================================================================
3764 //function : VUpdate
3765 //purpose  :
3766 //===============================================================================================
3767 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
3768 {
3769   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3770   if (aContextAIS.IsNull())
3771   {
3772     std::cout << theArgVec[0] << "AIS context is not available.\n";
3773     return 1;
3774   }
3775
3776   if (theArgsNb < 2)
3777   {
3778     std::cout << theArgVec[0] << ": insufficient arguments. Type help for more information.\n";
3779     return 1;
3780   }
3781
3782   const ViewerTest_DoubleMapOfInteractiveAndName& anAISMap = GetMapOfAIS();
3783
3784   AIS_ListOfInteractive aListOfIO;
3785
3786   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
3787   {
3788     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
3789
3790     Handle(AIS_InteractiveObject) anAISObj;
3791     if (anAISMap.IsBound2 (aName))
3792     {
3793       anAISObj = Handle(AIS_InteractiveObject)::DownCast (anAISMap.Find2 (aName));
3794     }
3795
3796     if (anAISObj.IsNull())
3797     {
3798       std::cout << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".\n";
3799       return 1;
3800     }
3801
3802     aListOfIO.Append (anAISObj);
3803   }
3804
3805   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
3806   for (; anIOIt.More(); anIOIt.Next())
3807   {
3808     aContextAIS->Update (anIOIt.Value(), Standard_False);
3809   }
3810
3811   aContextAIS->UpdateCurrentViewer();
3812
3813   return 0;
3814 }
3815
3816 //==============================================================================
3817 //function : VPerf
3818 //purpose  : Test the annimation of an object along a
3819 //           predifined trajectory
3820 //Draw arg : vperf ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)
3821 //==============================================================================
3822
3823 static int VPerf(Draw_Interpretor& di, Standard_Integer , const char** argv) {
3824
3825   OSD_Timer myTimer;
3826   if (TheAISContext()->HasOpenedContext())
3827     TheAISContext()->CloseLocalContext();
3828
3829   Standard_Real Step=4*M_PI/180;
3830   Standard_Real Angle=0;
3831
3832   Handle(AIS_InteractiveObject) aIO;
3833   if (GetMapOfAIS().IsBound2(argv[1]))
3834     aIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
3835   if (aIO.IsNull())
3836     return 1;
3837
3838   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aIO);
3839
3840   myTimer.Start();
3841
3842   if (Draw::Atoi(argv[3])==1 ) {
3843     di<<" Primitives sensibles OFF"<<"\n";
3844     TheAISContext()->Deactivate(aIO);
3845   }
3846   else {
3847     di<<" Primitives sensibles ON"<<"\n";
3848   }
3849   // Movement par transformation
3850   if(Draw::Atoi(argv[2]) ==1) {
3851     di<<" Calcul par Transformation"<<"\n";
3852     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3853
3854       Angle=Step*myAngle;
3855       gp_Trsf myTransfo;
3856       myTransfo.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ) ,Angle );
3857       TheAISContext()->SetLocation(aShape,myTransfo);
3858       TheAISContext() ->UpdateCurrentViewer();
3859
3860     }
3861   }
3862   else {
3863     di<<" Calcul par Locations"<<"\n";
3864     gp_Trsf myAngleTrsf;
3865     myAngleTrsf.SetRotation(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1) ), Step  );
3866     TopLoc_Location myDeltaAngle (myAngleTrsf);
3867     TopLoc_Location myTrueLoc;
3868
3869     for (Standard_Real myAngle=0;Angle<10*2*M_PI; myAngle++) {
3870
3871       Angle=Step*myAngle;
3872       myTrueLoc=myTrueLoc*myDeltaAngle;
3873       TheAISContext()->SetLocation(aShape,myTrueLoc );
3874       TheAISContext() ->UpdateCurrentViewer();
3875     }
3876   }
3877   if (Draw::Atoi(argv[3])==1 ){
3878     // On reactive la selection des primitives sensibles
3879     TheAISContext()->Activate(aIO,0);
3880   }
3881   a3DView() -> Redraw();
3882   myTimer.Stop();
3883   di<<" Temps ecoule "<<"\n";
3884   myTimer.Show();
3885   return 0;
3886 }
3887
3888
3889 //==================================================================================
3890 // Function : VAnimation
3891 //==================================================================================
3892 static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
3893   if (argc != 5) {
3894     di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile"<<"\n";
3895     return 1;
3896   }
3897
3898   Standard_Real thread = 4;
3899   Standard_Real angleA=0;
3900   Standard_Real angleB;
3901   Standard_Real X;
3902   gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
3903
3904   BRep_Builder B;
3905   TopoDS_Shape CrankArm;
3906   TopoDS_Shape CylinderHead;
3907   TopoDS_Shape Propeller;
3908   TopoDS_Shape EngineBlock;
3909
3910   //BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
3911   //BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
3912   //BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
3913   //BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
3914   BRepTools::Read(CrankArm,argv[1],B);
3915   BRepTools::Read(CylinderHead,argv[2],B);
3916   BRepTools::Read(Propeller,argv[3],B);
3917   BRepTools::Read(EngineBlock,argv[4],B);
3918
3919   if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure."<<"\n";}
3920
3921
3922   OSD_Timer myTimer;
3923   myTimer.Start();
3924
3925   Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
3926   Handle(AIS_Shape) myAisEngineBlock  = new AIS_Shape (EngineBlock);
3927   Handle(AIS_Shape) myAisCrankArm     = new AIS_Shape (CrankArm);
3928   Handle(AIS_Shape) myAisPropeller    = new AIS_Shape (Propeller);
3929
3930   GetMapOfAIS().Bind(myAisCylinderHead,"a");
3931   GetMapOfAIS().Bind(myAisEngineBlock,"b");
3932   GetMapOfAIS().Bind(myAisCrankArm,"c");
3933   GetMapOfAIS().Bind(myAisPropeller,"d");
3934
3935   myAisCylinderHead->SetMutable (Standard_True);
3936   myAisEngineBlock ->SetMutable (Standard_True);
3937   myAisCrankArm    ->SetMutable (Standard_True);
3938   myAisPropeller   ->SetMutable (Standard_True);
3939
3940   TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
3941   TheAISContext()->SetColor (myAisEngineBlock,  Quantity_NOC_RED);
3942   TheAISContext()->SetColor (myAisPropeller,    Quantity_NOC_GREEN);
3943
3944   TheAISContext()->Display (myAisCylinderHead, Standard_False);
3945   TheAISContext()->Display (myAisEngineBlock,  Standard_False);
3946   TheAISContext()->Display (myAisCrankArm,     Standard_False);
3947   TheAISContext()->Display (myAisPropeller,    Standard_False);
3948
3949   TheAISContext()->Deactivate(myAisCylinderHead);
3950   TheAISContext()->Deactivate(myAisEngineBlock );
3951   TheAISContext()->Deactivate(myAisCrankArm    );
3952   TheAISContext()->Deactivate(myAisPropeller   );
3953
3954   // Boucle de mouvement
3955   for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
3956
3957     angleA = thread*myAngle*M_PI/180;
3958     X = Sin(angleA)*3/8;
3959     angleB = atan(X / Sqrt(-X * X + 1));
3960     Standard_Real decal(25*0.6);
3961
3962
3963     //Build a transformation on the display
3964     gp_Trsf aPropellerTrsf;
3965     aPropellerTrsf.SetRotation(Ax1,angleA);
3966     TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
3967
3968     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));
3969     gp_Trsf aCrankArmTrsf;
3970     aCrankArmTrsf.SetTransformation(   base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
3971     TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
3972
3973     TheAISContext()->UpdateCurrentViewer();
3974   }
3975
3976   TopoDS_Shape myNewCrankArm  =myAisCrankArm ->Shape().Located( myAisCrankArm ->Transformation() );
3977   TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Transformation() );
3978
3979   myAisCrankArm ->ResetTransformation();
3980   myAisPropeller->ResetTransformation();
3981
3982   myAisCrankArm  -> Set(myNewCrankArm );
3983   myAisPropeller -> Set(myNewPropeller);
3984
3985   TheAISContext()->Activate(myAisCylinderHead,0);
3986   TheAISContext()->Activate(myAisEngineBlock,0 );
3987   TheAISContext()->Activate(myAisCrankArm ,0   );
3988   TheAISContext()->Activate(myAisPropeller ,0  );
3989
3990   myTimer.Stop();
3991   myTimer.Show();
3992   myTimer.Start();
3993
3994   TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
3995   TheAISContext()->Redisplay(myAisPropeller,Standard_False);
3996
3997   TheAISContext()->UpdateCurrentViewer();
3998   a3DView()->Redraw();
3999
4000   myTimer.Stop();
4001   myTimer.Show();
4002
4003   return 0;
4004
4005 }
4006
4007 //==============================================================================
4008 //function : VShading
4009 //purpose  : Sharpen or roughten the quality of the shading
4010 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
4011 //==============================================================================
4012 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
4013 {
4014   Standard_Real    myDevCoef;
4015   Handle(AIS_InteractiveObject) TheAisIO;
4016
4017   // Verifications
4018   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
4019
4020   if (TheAISContext()->HasOpenedContext())
4021     TheAISContext()->CloseLocalContext();
4022
4023   if (argc < 3) {
4024     myDevCoef  = 0.0008;
4025   } else {
4026     myDevCoef  =Draw::Atof(argv[2]);
4027   }
4028
4029   TCollection_AsciiString name=argv[1];
4030   if (GetMapOfAIS().IsBound2(name ))
4031     TheAisIO = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
4032   if (TheAisIO.IsNull())
4033     TheAisIO=GetAISShapeFromName((const char *)name.ToCString());
4034
4035   if (HaveToSet)
4036     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
4037   else
4038     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
4039
4040   TheAISContext()->Redisplay(TheAisIO);
4041   return 0;
4042 }
4043 //==============================================================================
4044 //function : HaveMode
4045 //use      : VActivatedModes
4046 //==============================================================================
4047 #include <TColStd_ListIteratorOfListOfInteger.hxx>
4048
4049 Standard_Boolean  HaveMode(const Handle(AIS_InteractiveObject)& TheAisIO,const Standard_Integer mode  )
4050 {
4051   TColStd_ListOfInteger List;
4052   TheAISContext()->ActivatedModes (TheAisIO,List);
4053   TColStd_ListIteratorOfListOfInteger it;
4054   Standard_Boolean Found=Standard_False;
4055   for (it.Initialize(List); it.More()&&!Found; it.Next() ){
4056     if (it.Value()==mode ) Found=Standard_True;
4057   }
4058   return Found;
4059 }
4060
4061
4062
4063 //==============================================================================
4064 //function : VActivatedMode
4065 //author   : ege
4066 //purpose  : permet d'attribuer a chacune des shapes un mode d'activation
4067 //           (edges,vertex...)qui lui est propre et le mode de selection standard.
4068 //           La fonction s'applique aux shapes selectionnees(current ou selected dans le viewer)
4069 //             Dans le cas ou on veut psser la shape en argument, la fonction n'autorise
4070 //           qu'un nom et qu'un mode.
4071 //Draw arg : vsetam  [ShapeName] mode(0,1,2,3,4,5,6,7)
4072 //==============================================================================
4073 #include <AIS_ListIteratorOfListOfInteractive.hxx>
4074
4075 static int VActivatedMode (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4076
4077 {
4078   Standard_Boolean ThereIsName = Standard_False ;
4079
4080   if(!a3DView().IsNull()){
4081
4082     const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetam") == 0);
4083     // verification des arguments
4084     if (HaveToSet) {
4085       if (argc<2||argc>3) { di<<" Syntaxe error"<<"\n";return 1;}
4086       ThereIsName = (argc == 3);
4087     }
4088     else {
4089       // vunsetam
4090       if (argc>1) {di<<" Syntaxe error"<<"\n";return 1;}
4091       else {
4092         di<<" R.A.Z de tous les modes de selecion"<<"\n";
4093         di<<" Fermeture du Context local"<<"\n";
4094         if (TheAISContext()->HasOpenedContext())
4095           TheAISContext()->CloseLocalContext();
4096       }
4097     }
4098
4099     // IL n'y a aps de nom de shape passe en argument
4100     if (HaveToSet && !ThereIsName){
4101       Standard_Integer aMode=Draw::Atoi(argv [1]);
4102
4103       const char *cmode="???";
4104       switch (aMode) {
4105       case 0: cmode = "Shape"; break;
4106       case 1: cmode = "Vertex"; break;
4107       case 2: cmode = "Edge"; break;
4108       case 3: cmode = "Wire"; break;
4109       case 4: cmode = "Face"; break;
4110       case 5: cmode = "Shell"; break;
4111       case 6: cmode = "Solid"; break;
4112       case 7: cmode = "Compound"; break;
4113       }
4114
4115       if( !TheAISContext()->HasOpenedContext() ) {
4116         // il n'y a pas de Context local d'ouvert
4117         // on en ouvre un et on charge toutes les shapes displayees
4118         // on load tous les objets displayees et on Activate les objets de la liste
4119         AIS_ListOfInteractive ListOfIO;
4120         // on sauve dans une AISListOfInteractive tous les objets currents
4121         if (TheAISContext()->NbSelected()>0 ){
4122           TheAISContext()->UnhilightSelected(Standard_False);
4123
4124           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
4125             ListOfIO.Append(TheAISContext()->SelectedInteractive() );
4126           }
4127         }
4128
4129         TheAISContext()->OpenLocalContext(Standard_False);
4130         ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4131           it (GetMapOfAIS());
4132         while(it.More()){
4133           Handle(AIS_InteractiveObject) aIO =
4134             Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4135           if (!aIO.IsNull())
4136             TheAISContext()->Load(aIO,0,Standard_False);
4137           it.Next();
4138         }
4139         // traitement des objets qui etaient currents dans le Contexte global
4140         if (!ListOfIO.IsEmpty() ) {
4141           // il y avait des objets currents
4142           AIS_ListIteratorOfListOfInteractive iter;
4143           for (iter.Initialize(ListOfIO); iter.More() ; iter.Next() ) {
4144             Handle(AIS_InteractiveObject) aIO=iter.Value();
4145             TheAISContext()->Activate(aIO,aMode);
4146             di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString()  <<"\n";
4147           }
4148         }
4149         else {
4150           // On applique le mode a tous les objets displayes
4151           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4152             it2 (GetMapOfAIS());
4153           while(it2.More()){
4154             Handle(AIS_InteractiveObject) aIO =
4155               Handle(AIS_InteractiveObject)::DownCast(it2.Key1());
4156             if (!aIO.IsNull()) {
4157               di<<" Mode: "<<cmode<<" ON pour "<<it2.Key2().ToCString() <<"\n";
4158               TheAISContext()->Activate(aIO,aMode);
4159             }
4160             it2.Next();
4161           }
4162         }
4163
4164       }
4165
4166       else {
4167         // un Context local est deja ouvert
4168         // Traitement des objets du Context local
4169         if (TheAISContext()->NbSelected()>0 ){
4170           TheAISContext()->UnhilightSelected(Standard_False);
4171           // il y a des objets selected,on les parcourt
4172           for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() ){
4173             Handle(AIS_InteractiveObject) aIO=TheAISContext()->SelectedInteractive();
4174
4175
4176             if (HaveMode(aIO,aMode) ) {
4177               di<<" Mode: "<<cmode<<" OFF pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4178               TheAISContext()->Deactivate(aIO,aMode);
4179             }
4180             else{
4181               di<<" Mode: "<<cmode<<" ON pour "<<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4182               TheAISContext()->Activate(aIO,aMode);
4183             }
4184
4185           }
4186         }
4187         else{
4188           // il n'y a pas d'objets selected
4189           // tous les objets diplayes sont traites
4190           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
4191             it (GetMapOfAIS());
4192           while(it.More()){
4193             Handle(AIS_InteractiveObject) aIO =
4194               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4195             if (!aIO.IsNull()) {
4196               if (HaveMode(aIO,aMode) ) {
4197                 di<<" Mode: "<<cmode<<" OFF pour "
4198                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4199                 TheAISContext()->Deactivate(aIO,aMode);
4200               }
4201               else{
4202                 di<<" Mode: "<<cmode<<" ON pour"
4203                   <<GetMapOfAIS().Find1(aIO).ToCString() <<"\n";
4204                 TheAISContext()->Activate(aIO,aMode);
4205               }
4206             }
4207             it.Next();
4208           }
4209         }
4210       }
4211     }
4212     else if (HaveToSet && ThereIsName){
4213       Standard_Integer aMode=Draw::Atoi(argv [2]);
4214       Handle(AIS_InteractiveObject) aIO =
4215         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[1]));
4216
4217       if (!aIO.IsNull()) {
4218         const char *cmode="???";
4219
4220         switch (aMode) {
4221         case 0: cmode = "Shape"; break;
4222         case 1: cmode = "Vertex"; break;
4223         case 2: cmode = "Edge"; break;
4224         case 3: cmode = "Wire"; break;
4225         case 4: cmode = "Face"; break;
4226         case 5: cmode = "Shell"; break;
4227         case 6: cmode = "Solid"; break;
4228         case 7: cmode = "Compound"; break;
4229         }
4230
4231         if( !TheAISContext()->HasOpenedContext() ) {
4232           TheAISContext()->OpenLocalContext(Standard_False);
4233           // On charge tous les objets de la map
4234           ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName it (GetMapOfAIS());
4235           while(it.More()){
4236             Handle(AIS_InteractiveObject) aShape=
4237               Handle(AIS_InteractiveObject)::DownCast(it.Key1());
4238             if (!aShape.IsNull())
4239               TheAISContext()->Load(aShape,0,Standard_False);
4240             it.Next();
4241           }
4242           TheAISContext()->Activate(aIO,aMode);
4243           di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
4244         }
4245
4246         else {
4247           // un Context local est deja ouvert
4248           if (HaveMode(aIO,aMode) ) {
4249             di<<" Mode: "<<cmode<<" OFF pour "<<argv[1]<<"\n";
4250             TheAISContext()->Deactivate(aIO,aMode);
4251           }
4252           else{
4253             di<<" Mode: "<<cmode<<" ON pour "<<argv[1]<<"\n";
4254             TheAISContext()->Activate(aIO,aMode);
4255           }
4256         }
4257       }
4258     }
4259   }
4260   return 0;
4261 }
4262
4263 //! Auxiliary method to print Interactive Object information
4264 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
4265                      const Handle(Standard_Transient)&                     theObject,
4266                      Draw_Interpretor&                                     theDI)
4267 {
4268   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theObject);
4269   if (anObj.IsNull())
4270   {
4271     theDI << theObject->DynamicType()->Name() << " is not AIS presentation\n";
4272     return;
4273   }
4274
4275   theDI << (TheAISContext()->IsDisplayed  (anObj) ? "Displayed"  : "Hidden   ")
4276         << (TheAISContext()->IsSelected   (anObj) ? " Selected" : "         ")
4277         << (theDetected.Contains (anObj)          ? " Detected" : "         ")
4278         << " Type: ";
4279   if (anObj->Type() == AIS_KOI_Datum)
4280   {
4281     // AIS_Datum
4282     if      (anObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
4283     else if (anObj->Signature() == 2) { theDI << " AIS_Axis"; }
4284     else if (anObj->Signature() == 6) { theDI << " AIS_Circle"; }
4285     else if (anObj->Signature() == 5) { theDI << " AIS_Line"; }
4286     else if (anObj->Signature() == 7) { theDI << " AIS_Plane"; }
4287     else if (anObj->Signature() == 1) { theDI << " AIS_Point"; }
4288     else if (anObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
4289   }
4290   // AIS_Shape
4291   else if (anObj->Type()      == AIS_KOI_Shape
4292         && anObj->Signature() == 0)
4293   {
4294     theDI << " AIS_Shape";
4295   }
4296   else if (anObj->Type() == AIS_KOI_Relation)
4297   {
4298     // AIS_Dimention and AIS_Relation
4299     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (anObj);
4300     switch (aRelation->KindOfDimension())
4301     {
4302       case AIS_KOD_PLANEANGLE:     theDI << " AIS_AngleDimension"; break;
4303       case AIS_KOD_LENGTH:         theDI << " AIS_Chamf2/3dDimension/AIS_LengthDimension"; break;
4304       case AIS_KOD_DIAMETER:       theDI << " AIS_DiameterDimension"; break;
4305       case AIS_KOD_ELLIPSERADIUS:  theDI << " AIS_EllipseRadiusDimension"; break;
4306       //case AIS_KOD_FILLETRADIUS:   theDI << " AIS_FilletRadiusDimension "; break;
4307       case AIS_KOD_OFFSET:         theDI << " AIS_OffsetDimension"; break;
4308       case AIS_KOD_RADIUS:         theDI << " AIS_RadiusDimension"; break;
4309       default:                     theDI << " UNKNOWN dimension"; break;
4310     }
4311   }
4312   else
4313   {
4314     theDI << " UserPrs";
4315   }
4316   theDI << " (" << theObject->DynamicType()->Name() << ")";
4317 }
4318
4319 //! Print information about locally selected sub-shapes
4320 template <typename T>
4321 static void printLocalSelectionInfo (const T& theContext, Draw_Interpretor& theDI)
4322 {
4323   const Standard_Boolean isGlobalCtx = !(Handle(AIS_InteractiveContext)::DownCast (theContext).IsNull());
4324   TCollection_AsciiString aPrevName;
4325   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
4326   {
4327     const Handle(AIS_Shape) aShapeIO = Handle(AIS_Shape)::DownCast (theContext->SelectedInteractive());
4328     const Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
4329     if (aShapeIO.IsNull() || anOwner.IsNull())
4330       continue;
4331     if (isGlobalCtx)
4332     {
4333       if (anOwner == aShapeIO->GlobalSelOwner())
4334         continue;
4335     }
4336     const TopoDS_Shape      aSubShape = theContext->SelectedShape();
4337     if (aSubShape.IsNull()
4338       || aShapeIO.IsNull()
4339       || !GetMapOfAIS().IsBound1 (aShapeIO))
4340     {
4341       continue;
4342     }
4343
4344     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
4345     TopTools_MapOfShape aFilter;
4346     Standard_Integer    aNumber = 0;
4347     const TopoDS_Shape  aShape  = aShapeIO->Shape();
4348     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
4349          anIter.More(); anIter.Next())
4350     {
4351       if (!aFilter.Add (anIter.Current()))
4352       {
4353         continue; // filter duplicates
4354       }
4355
4356       ++aNumber;
4357       if (!anIter.Current().IsSame (aSubShape))
4358       {
4359         continue;
4360       }
4361
4362       Standard_CString aShapeName = NULL;
4363       switch (aSubShape.ShapeType())
4364       {
4365         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
4366         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
4367         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
4368         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
4369         case TopAbs_FACE:      aShapeName = "     Face"; break;
4370         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
4371         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
4372         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
4373         default:
4374         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
4375       }
4376
4377       if (aParentName != aPrevName)
4378       {
4379         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
4380         aPrevName = aParentName;
4381       }
4382       theDI << "  " << aShapeName << " #" << aNumber << "\n";
4383       break;
4384     }
4385   }
4386 }
4387
4388 //==============================================================================
4389 //function : VState
4390 //purpose  :
4391 //==============================================================================
4392 static Standard_Integer VState (Draw_Interpretor& theDI,
4393                                 Standard_Integer  theArgNb,
4394                                 Standard_CString* theArgVec)
4395 {
4396   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
4397   if (aCtx.IsNull())
4398   {
4399     std::cerr << "Error: No opened viewer!\n";
4400     return 1;
4401   }
4402
4403   Standard_Boolean toPrintEntities = Standard_False;
4404   Standard_Boolean toCheckSelected = Standard_False;
4405
4406   for (Standard_Integer anArgIdx = 1; anArgIdx < theArgNb; ++anArgIdx)
4407   {
4408     TCollection_AsciiString anOption (theArgVec[anArgIdx]);
4409     anOption.LowerCase();
4410     if (anOption == "-detectedentities"
4411       || anOption == "-entities")
4412     {
4413       toPrintEntities = Standard_True;
4414     }
4415     else if (anOption == "-hasselected")
4416     {
4417       toCheckSelected = Standard_True;
4418     }
4419   }
4420
4421   if (toCheckSelected)
4422   {
4423     aCtx->InitSelected();
4424     TCollection_AsciiString hasSelected (static_cast<Standard_Integer> (aCtx->HasSelectedShape()));
4425     theDI << "Check if context has selected shape: " << hasSelected << "\n";
4426
4427     return 0;
4428   }
4429
4430   if (toPrintEntities)
4431   {
4432     theDI << "Detected entities:\n";
4433     Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->HasOpenedContext() ? aCtx->LocalSelector() : aCtx->MainSelector();
4434     SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager();
4435     for (aSelector->InitDetected(); aSelector->MoreDetected(); aSelector->NextDetected())
4436     {
4437       const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity();
4438       Handle(SelectMgr_EntityOwner) anOwner    = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
4439       Handle(AIS_InteractiveObject) anObj      = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
4440       gp_Trsf anInvTrsf;
4441       if (anObj->TransformPersistence().Flags)
4442       {
4443         const Graphic3d_Mat4d& aProjection = aMgr.ProjectionMatrix();
4444         const Graphic3d_Mat4d& aWorldView  = aMgr.WorldViewMatrix();
4445
4446         Graphic3d_Mat4d aMat = anObj->TransformPersistence().Compute (aProjection, aWorldView, 0, 0);
4447         anInvTrsf.SetValues (aMat.GetValue (0, 0), aMat.GetValue (0, 1), aMat.GetValue (0, 2), aMat.GetValue (0, 3),
4448           aMat.GetValue (1, 0), aMat.GetValue (1, 1), aMat.GetValue (1, 2), aMat.GetValue (1, 3),
4449           aMat.GetValue (2, 0), aMat.GetValue (2, 1), aMat.GetValue (2, 2), aMat.GetValue (2, 3));
4450         anInvTrsf.Invert();
4451       }
4452       if (anObj->HasTransformation())
4453       {
4454         anInvTrsf = anObj->InversedTransformation() * anInvTrsf;
4455       }
4456       if (anEntity->HasInitLocation())
4457       {
4458         anInvTrsf = anEntity->InvInitLocation() * anInvTrsf;
4459       }
4460       const Standard_Integer aScale = anEntity->SensitivityFactor() < aSelector->PixelTolerance()
4461         ? anEntity->SensitivityFactor() : 1;
4462       const Standard_Boolean isToScaleAndTransform = anInvTrsf.Form() != gp_Identity || aScale != 1;
4463       SelectMgr_SelectingVolumeManager anEntMgr =
4464         isToScaleAndTransform ? aMgr.ScaleAndTransform (aScale, anInvTrsf)
4465                               : aMgr;
4466       SelectBasics_PickResult aResult;
4467       anEntity->Matches (anEntMgr, aResult);
4468       gp_Pnt aDetectedPnt = anInvTrsf.Form() == gp_Identity ?
4469         anEntMgr.DetectedPoint (aResult.Depth()) : anEntMgr.DetectedPoint (aResult.Depth()).Transformed (anInvTrsf.Inverted());
4470
4471       TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
4472       aName.LeftJustify (20, ' ');
4473       char anInfoStr[512];
4474       Sprintf (anInfoStr,
4475                " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f",
4476                aResult.Depth(),
4477                aResult.DistToGeomCenter(),
4478                aDetectedPnt.X(), aDetectedPnt.Y(), aDetectedPnt.Z());
4479       theDI << "  " << aName
4480             << anInfoStr
4481             << " (" << anEntity->DynamicType()->Name() << ")"
4482             << "\n";
4483
4484       Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
4485       if (!aBRepOwner.IsNull())
4486       {
4487         theDI << "                       Detected Shape: "
4488               << aBRepOwner->Shape().TShape()->DynamicType()->Name()
4489               << "\n";
4490       }
4491
4492       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast (anEntity);
4493       if (!aWire.IsNull())
4494       {
4495         Handle(Select3D_SensitiveEntity) aSen = aWire->GetLastDetected();
4496         theDI << "                       Detected Child: "
4497               << aSen->DynamicType()->Name()
4498               << "\n";
4499       }
4500     }
4501     return 0;
4502   }
4503
4504   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
4505   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
4506   {
4507     aDetected.Add (aCtx->DetectedCurrentObject());
4508   }
4509
4510   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
4511   if (theArgNb >= 2
4512    && !toShowAll)
4513   {
4514     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4515     {
4516       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
4517       if (!GetMapOfAIS().IsBound2 (anObjName))
4518       {
4519         theDI << anObjName << " doesn't exist!\n";
4520         continue;
4521       }
4522
4523       const Handle(Standard_Transient) anObjTrans = GetMapOfAIS().Find2 (anObjName);
4524       TCollection_AsciiString aName = anObjName;
4525       aName.LeftJustify (20, ' ');
4526       theDI << "  " << aName << " ";
4527       objInfo (aDetected, anObjTrans, theDI);
4528       theDI << "\n";
4529     }
4530     return 0;
4531   }
4532
4533   if (!aCtx->HasOpenedContext() && aCtx->NbSelected() > 0 && !toShowAll)
4534   {
4535     NCollection_DataMap<Handle(SelectMgr_EntityOwner), TopoDS_Shape> anOwnerShapeMap;
4536     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
4537     {
4538       const Handle(SelectMgr_EntityOwner) anOwner = aCtx->SelectedOwner();
4539       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
4540       // handle whole object selection
4541       if (anOwner == anObj->GlobalSelOwner())
4542       {
4543         TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
4544         aName.LeftJustify (20, ' ');
4545         theDI << aName << " ";
4546         objInfo (aDetected, anObj, theDI);
4547         theDI << "\n";
4548       }
4549     }
4550
4551     // process selected sub-shapes
4552     printLocalSelectionInfo (aCtx, theDI);
4553
4554     return 0;
4555   }
4556
4557   theDI << "Neutral-point state:\n";
4558   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4559        anObjIter.More(); anObjIter.Next())
4560   {
4561     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anObjIter.Key1());
4562     if (anObj.IsNull())
4563     {
4564       continue;
4565     }
4566
4567     TCollection_AsciiString aName = anObjIter.Key2();
4568     aName.LeftJustify (20, ' ');
4569     theDI << "  " << aName << " ";
4570     objInfo (aDetected, anObj, theDI);
4571     theDI << "\n";
4572   }
4573   printLocalSelectionInfo (aCtx, theDI);
4574   if (aCtx->HasOpenedContext())
4575     printLocalSelectionInfo (aCtx->LocalContext(), theDI);
4576   return 0;
4577 }
4578
4579 //=======================================================================
4580 //function : PickObjects
4581 //purpose  :
4582 //=======================================================================
4583 Standard_Boolean  ViewerTest::PickObjects(Handle(TColStd_HArray1OfTransient)& arr,
4584                                           const AIS_KindOfInteractive TheType,
4585                                           const Standard_Integer TheSignature,
4586                                           const Standard_Integer MaxPick)
4587 {
4588   Handle(AIS_InteractiveObject) IO;
4589   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
4590
4591   // step 1: prepare the data
4592   if(curindex !=0){
4593     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
4594     TheAISContext()->AddFilter(F1);
4595   }
4596
4597   // step 2 : wait for the selection...
4598   Standard_Integer NbPickGood (0),NbToReach(arr->Length());
4599   Standard_Integer NbPickFail(0);
4600   Standard_Integer argccc = 5;
4601   const char *bufff[] = { "A", "B", "C","D", "E" };
4602   const char **argvvv = (const char **) bufff;
4603
4604
4605   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
4606     while(ViewerMainLoop(argccc,argvvv)){}
4607     Standard_Integer NbStored = TheAISContext()->NbSelected();
4608     if(NbStored != NbPickGood)
4609       NbPickGood= NbStored;
4610     else
4611       NbPickFail++;
4612     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<endl;
4613   }
4614
4615   // step3 get result.
4616
4617   if (NbPickFail >= NbToReach)
4618     return Standard_False;
4619
4620   Standard_Integer i(0);
4621   for(TheAISContext()->InitSelected();
4622       TheAISContext()->MoreSelected();
4623       TheAISContext()->NextSelected()){
4624     i++;
4625     Handle(AIS_InteractiveObject) IO2 = TheAISContext()->SelectedInteractive();
4626     arr->SetValue(i,IO2);
4627   }
4628
4629
4630   if(curindex>0)
4631     TheAISContext()->CloseLocalContext(curindex);
4632
4633   return Standard_True;
4634 }
4635
4636
4637 //=======================================================================
4638 //function : PickObject
4639 //purpose  :
4640 //=======================================================================
4641 Handle(AIS_InteractiveObject) ViewerTest::PickObject(const AIS_KindOfInteractive TheType,
4642                                                      const Standard_Integer TheSignature,
4643                                                      const Standard_Integer MaxPick)
4644 {
4645   Handle(AIS_InteractiveObject) IO;
4646   Standard_Integer curindex = (TheType == AIS_KOI_None) ? 0 : TheAISContext()->OpenLocalContext();
4647
4648   // step 1: prepare the data
4649
4650   if(curindex !=0){
4651     Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(TheType,TheSignature);
4652     TheAISContext()->AddFilter(F1);
4653   }
4654
4655   // step 2 : wait for the selection...
4656   Standard_Boolean IsGood (Standard_False);
4657   Standard_Integer NbPick(0);
4658   Standard_Integer argccc = 5;
4659   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
4660   const char **argvvv = (const char **) bufff;
4661
4662
4663   while(!IsGood && NbPick<= MaxPick){
4664     while(ViewerMainLoop(argccc,argvvv)){}
4665     IsGood = (TheAISContext()->NbSelected()>0) ;
4666     NbPick++;
4667     cout<<"Nb Pick :"<<NbPick<<endl;
4668   }
4669
4670
4671   // step3 get result.
4672   if(IsGood){
4673     TheAISContext()->InitSelected();
4674     IO = TheAISContext()->SelectedInteractive();
4675   }
4676
4677   if(curindex!=0)
4678     TheAISContext()->CloseLocalContext(curindex);
4679   return IO;
4680 }
4681
4682 //=======================================================================
4683 //function : PickShape
4684 //purpose  : First Activate the rightmode + Put Filters to be able to
4685 //           pick objets that are of type <TheType>...
4686 //=======================================================================
4687
4688 TopoDS_Shape ViewerTest::PickShape(const TopAbs_ShapeEnum TheType,
4689                                    const Standard_Integer MaxPick)
4690 {
4691
4692   // step 1: prepare the data
4693
4694   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
4695   TopoDS_Shape result;
4696
4697   if(TheType==TopAbs_SHAPE){
4698     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
4699     TheAISContext()->AddFilter(F1);
4700   }
4701   else{
4702     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
4703     TheAISContext()->AddFilter(TF);
4704     TheAISContext()->ActivateStandardMode(TheType);
4705
4706   }
4707
4708
4709   // step 2 : wait for the selection...
4710   Standard_Boolean NoShape (Standard_True);
4711   Standard_Integer NbPick(0);
4712   Standard_Integer argccc = 5;
4713   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
4714   const char **argvvv = (const char **) bufff;
4715
4716
4717   while(NoShape && NbPick<= MaxPick){
4718     while(ViewerMainLoop(argccc,argvvv)){}
4719     NoShape = (TheAISContext()->NbSelected()==0) ;
4720     NbPick++;
4721     cout<<"Nb Pick :"<<NbPick<<endl;
4722   }
4723
4724   // step3 get result.
4725
4726   if(!NoShape){
4727
4728     TheAISContext()->InitSelected();
4729     if(TheAISContext()->HasSelectedShape())
4730       result = TheAISContext()->SelectedShape();
4731     else{
4732       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4733       result = Handle(AIS_Shape)::DownCast (IO)->Shape();
4734     }
4735   }
4736
4737   if(curindex>0)
4738     TheAISContext()->CloseLocalContext(curindex);
4739
4740   return result;
4741 }
4742
4743
4744 //=======================================================================
4745 //function : PickShapes
4746 //purpose  :
4747 //=======================================================================
4748 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum TheType,
4749                                          Handle(TopTools_HArray1OfShape)& thearr,
4750                                          const Standard_Integer MaxPick)
4751 {
4752
4753   Standard_Integer Taille = thearr->Length();
4754   if(Taille>1)
4755     cout<<" WARNING : Pick with Shift+ MB1 for Selection of more than 1 object"<<"\n";
4756
4757   // step 1: prepare the data
4758   Standard_Integer curindex = TheAISContext()->OpenLocalContext();
4759   if(TheType==TopAbs_SHAPE){
4760     Handle(AIS_TypeFilter) F1 = new AIS_TypeFilter(AIS_KOI_Shape);
4761     TheAISContext()->AddFilter(F1);
4762   }
4763   else{
4764     Handle(StdSelect_ShapeTypeFilter) TF = new StdSelect_ShapeTypeFilter(TheType);
4765     TheAISContext()->AddFilter(TF);
4766     TheAISContext()->ActivateStandardMode(TheType);
4767
4768   }
4769
4770   // step 2 : wait for the selection...
4771   Standard_Integer NbPickGood (0),NbToReach(thearr->Length());
4772   Standard_Integer NbPickFail(0);
4773   Standard_Integer argccc = 5;
4774   const char *bufff[] = { "A", "B", "C","D", "E" };
4775   const char **argvvv = (const char **) bufff;
4776
4777
4778   while(NbPickGood<NbToReach && NbPickFail <= MaxPick){
4779     while(ViewerMainLoop(argccc,argvvv)){}
4780     Standard_Integer NbStored = TheAISContext()->NbSelected();
4781     if (NbStored != NbPickGood)
4782       NbPickGood= NbStored;
4783     else
4784       NbPickFail++;
4785     cout<<"NbPicked =  "<<NbPickGood<<" |  Nb Pick Fail :"<<NbPickFail<<"\n";
4786   }
4787
4788   // step3 get result.
4789
4790   if (NbPickFail >= NbToReach)
4791     return Standard_False;
4792
4793   Standard_Integer i(0);
4794   for(TheAISContext()->InitSelected();TheAISContext()->MoreSelected();TheAISContext()->NextSelected()){
4795     i++;
4796     if(TheAISContext()->HasSelectedShape())
4797       thearr->SetValue(i,TheAISContext()->SelectedShape());
4798     else{
4799       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4800       thearr->SetValue(i,Handle(AIS_Shape)::DownCast (IO)->Shape());
4801     }
4802   }
4803
4804   TheAISContext()->CloseLocalContext(curindex);
4805   return Standard_True;
4806 }
4807
4808
4809 //=======================================================================
4810 //function : VPickShape
4811 //purpose  :
4812 //=======================================================================
4813 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4814 {
4815   TopoDS_Shape PickSh;
4816   TopAbs_ShapeEnum theType = TopAbs_COMPOUND;
4817
4818   if(argc==1)
4819     theType = TopAbs_SHAPE;
4820   else{
4821     if(!strcasecmp(argv[1],"V" )) theType = TopAbs_VERTEX;
4822     else if (!strcasecmp(argv[1],"E" )) theType = TopAbs_EDGE;
4823     else if (!strcasecmp(argv[1],"W" )) theType = TopAbs_WIRE;
4824     else if (!strcasecmp(argv[1],"F" )) theType = TopAbs_FACE;
4825     else if(!strcasecmp(argv[1],"SHAPE" )) theType = TopAbs_SHAPE;
4826     else if (!strcasecmp(argv[1],"SHELL" )) theType = TopAbs_SHELL;
4827     else if (!strcasecmp(argv[1],"SOLID" )) theType = TopAbs_SOLID;
4828   }
4829
4830   static Standard_Integer nbOfSub[8]={0,0,0,0,0,0,0,0};
4831   static TCollection_AsciiString nameType[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
4832
4833   TCollection_AsciiString name;
4834
4835
4836   Standard_Integer NbToPick = argc>2 ? argc-2 : 1;
4837   if(NbToPick==1){
4838     PickSh = ViewerTest::PickShape(theType);
4839
4840     if(PickSh.IsNull())
4841       return 1;
4842     if(argc>2){
4843       name += argv[2];
4844     }
4845     else{
4846
4847       if(!PickSh.IsNull()){
4848         nbOfSub[Standard_Integer(theType)]++;
4849         name += "Picked_";
4850         name += nameType[Standard_Integer(theType)];
4851         TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
4852         name +="_";
4853         name+=indxstring;
4854       }
4855     }
4856     // si on avait une petite methode pour voir si la shape
4857     // est deja dans la Double map, ca eviterait de creer....
4858     DBRep::Set(name.ToCString(),PickSh);
4859
4860     Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
4861     GetMapOfAIS().Bind(newsh, name);
4862     TheAISContext()->Display(newsh);
4863     di<<"Nom de la shape pickee : "<<name.ToCString()<<"\n";
4864   }
4865
4866   // Plusieurs objets a picker, vite vite vite....
4867   //
4868   else{
4869     Standard_Boolean autonaming = !strcasecmp(argv[2],".");
4870     Handle(TopTools_HArray1OfShape) arr = new TopTools_HArray1OfShape(1,NbToPick);
4871     if(ViewerTest::PickShapes(theType,arr)){
4872       for(Standard_Integer i=1;i<=NbToPick;i++){
4873         PickSh = arr->Value(i);
4874         if(!PickSh.IsNull()){
4875           if(autonaming){
4876             nbOfSub[Standard_Integer(theType)]++;
4877             name.Clear();
4878             name += "Picked_";
4879             name += nameType[Standard_Integer(theType)];
4880             TCollection_AsciiString indxstring(nbOfSub[Standard_Integer(theType)]);
4881             name +="_";
4882             name+=indxstring;
4883           }
4884         }
4885         else
4886           name = argv[1+i];
4887
4888         DBRep::Set(name.ToCString(),PickSh);
4889         Handle(AIS_Shape) newsh = new AIS_Shape(PickSh);
4890         GetMapOfAIS().Bind(newsh, name);
4891         di<<"display of picke shape #"<<i<<" - nom : "<<name.ToCString()<<"\n";
4892         TheAISContext()->Display(newsh);
4893
4894       }
4895     }
4896   }
4897   return 0;
4898 }
4899
4900 //=======================================================================
4901 //function : VPickSelected
4902 //purpose  :
4903 //=======================================================================
4904 static int VPickSelected (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgs)
4905 {
4906   static Standard_Integer aCount = 0;
4907   TCollection_AsciiString aName = "PickedShape_";
4908
4909   if (theArgNb > 1)
4910   {
4911     aName = theArgs[1];
4912   }
4913   else
4914   {
4915     aName = aName + aCount++ + "_";
4916   }
4917
4918   Standard_Integer anIdx = 0;
4919   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected(), ++anIdx)
4920   {
4921     TopoDS_Shape aShape;
4922     if (TheAISContext()->HasSelectedShape())
4923     {
4924       aShape = TheAISContext()->SelectedShape();
4925     }
4926     else
4927     {
4928       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
4929       aShape = Handle(AIS_Shape)::DownCast (IO)->Shape();
4930     }
4931
4932     TCollection_AsciiString aCurrentName = aName;
4933     if (anIdx > 0)
4934     {
4935       aCurrentName += anIdx;
4936     }
4937
4938     DBRep::Set ((aCurrentName).ToCString(), aShape);
4939
4940     Handle(AIS_Shape) aNewShape = new AIS_Shape (aShape);
4941     GetMapOfAIS().Bind (aNewShape, aCurrentName);
4942     TheAISContext()->Display (aNewShape);
4943   }
4944
4945   return 0;
4946 }
4947
4948 //=======================================================================
4949 //function : list of known objects
4950 //purpose  :
4951 //=======================================================================
4952 static int VIOTypes( Draw_Interpretor& di, Standard_Integer , const char** )
4953 {
4954   //                             1234567890         12345678901234567         123456789
4955   TCollection_AsciiString Colum [3]={"Standard Types","Type Of Object","Signature"};
4956   TCollection_AsciiString BlankLine(64,'_');
4957   Standard_Integer i ;
4958
4959   di<<"/n"<<BlankLine.ToCString()<<"\n";
4960
4961   for( i =0;i<=2;i++)
4962     Colum[i].Center(20,' ');
4963   for(i=0;i<=2;i++)
4964     di<<"|"<<Colum[i].ToCString();
4965   di<<"|"<<"\n";
4966
4967   di<<BlankLine.ToCString()<<"\n";
4968
4969   //  TCollection_AsciiString thetypes[5]={"Datum","Shape","Object","Relation","None"};
4970   const char ** names = GetTypeNames();
4971
4972   TCollection_AsciiString curstring;
4973   TCollection_AsciiString curcolum[3];
4974
4975
4976   // les objets de type Datum..
4977   curcolum[1]+="Datum";
4978   for(i =0;i<=6;i++){
4979     curcolum[0].Clear();
4980     curcolum[0] += names[i];
4981
4982     curcolum[2].Clear();
4983     curcolum[2]+=TCollection_AsciiString(i+1);
4984
4985     for(Standard_Integer j =0;j<=2;j++){
4986       curcolum[j].Center(20,' ');
4987       di<<"|"<<curcolum[j].ToCString();
4988     }
4989     di<<"|"<<"\n";
4990   }
4991   di<<BlankLine.ToCString()<<"\n";
4992
4993   // les objets de type shape
4994   curcolum[1].Clear();
4995   curcolum[1]+="Shape";
4996   curcolum[1].Center(20,' ');
4997
4998   for(i=0;i<=2;i++){
4999     curcolum[0].Clear();
5000     curcolum[0] += names[7+i];
5001     curcolum[2].Clear();
5002     curcolum[2]+=TCollection_AsciiString(i);
5003
5004     for(Standard_Integer j =0;j<=2;j++){
5005       curcolum[j].Center(20,' ');
5006       di<<"|"<<curcolum[j].ToCString();
5007     }
5008     di<<"|"<<"\n";
5009   }
5010   di<<BlankLine.ToCString()<<"\n";
5011   // les IO de type objet...
5012   curcolum[1].Clear();
5013   curcolum[1]+="Object";
5014   curcolum[1].Center(20,' ');
5015   for(i=0;i<=1;i++){
5016     curcolum[0].Clear();
5017     curcolum[0] += names[10+i];
5018     curcolum[2].Clear();
5019     curcolum[2]+=TCollection_AsciiString(i);
5020
5021     for(Standard_Integer j =0;j<=2;j++){
5022       curcolum[j].Center(20,' ');
5023       di<<"|"<<curcolum[j].ToCString();
5024     }
5025     di<<"|"<<"\n";
5026   }
5027   di<<BlankLine.ToCString()<<"\n";
5028   // les contraintes et dimensions.
5029   // pour l'instant on separe juste contraintes et dimensions...
5030   // plus tard, on detaillera toutes les sortes...
5031   curcolum[1].Clear();
5032   curcolum[1]+="Relation";
5033   curcolum[1].Center(20,' ');
5034   for(i=0;i<=1;i++){
5035     curcolum[0].Clear();
5036     curcolum[0] += names[12+i];
5037     curcolum[2].Clear();
5038     curcolum[2]+=TCollection_AsciiString(i);
5039
5040     for(Standard_Integer j =0;j<=2;j++){
5041       curcolum[j].Center(20,' ');
5042       di<<"|"<<curcolum[j].ToCString();
5043     }
5044     di<<"|"<<"\n";
5045   }
5046   di<<BlankLine.ToCString()<<"\n";
5047
5048
5049   return 0;
5050 }
5051
5052
5053 static int VEraseType( Draw_Interpretor& , Standard_Integer argc, const char** argv)
5054 {
5055   if(argc!=2) return 1;
5056
5057   AIS_KindOfInteractive TheType;
5058   Standard_Integer TheSign(-1);
5059   GetTypeAndSignfromString(argv[1],TheType,TheSign);
5060
5061
5062   AIS_ListOfInteractive LIO;
5063
5064   // en attendant l'amelioration ais pour les dimensions...
5065   //
5066   Standard_Integer dimension_status(-1);
5067   if(TheType==AIS_KOI_Relation){
5068     dimension_status = TheSign ==1 ? 1 : 0;
5069     TheSign=-1;
5070   }
5071
5072   TheAISContext()->DisplayedObjects(TheType,TheSign,LIO);
5073   Handle(AIS_InteractiveObject) curio;
5074   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
5075     curio  = it.Value();
5076
5077     if(dimension_status == -1)
5078       TheAISContext()->Erase(curio,Standard_False);
5079     else {
5080       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
5081       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
5082           (dimension_status==1 && KOD != AIS_KOD_NONE))
5083         TheAISContext()->Erase(curio,Standard_False);
5084     }
5085   }
5086   TheAISContext()->UpdateCurrentViewer();
5087   return 0;
5088 }
5089 static int VDisplayType(Draw_Interpretor& , Standard_Integer argc, const char** argv)
5090 {
5091   if(argc!=2) return 1;
5092
5093   AIS_KindOfInteractive TheType;
5094   Standard_Integer TheSign(-1);
5095   GetTypeAndSignfromString(argv[1],TheType,TheSign);
5096
5097   // en attendant l'amelioration ais pour les dimensions...
5098   //
5099   Standard_Integer dimension_status(-1);
5100   if(TheType==AIS_KOI_Relation){
5101     dimension_status = TheSign ==1 ? 1 : 0;
5102     TheSign=-1;
5103   }
5104
5105   AIS_ListOfInteractive LIO;
5106   TheAISContext()->ObjectsInside(LIO,TheType,TheSign);
5107   Handle(AIS_InteractiveObject) curio;
5108   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
5109     curio  = it.Value();
5110     if(dimension_status == -1)
5111       TheAISContext()->Display(curio,Standard_False);
5112     else {
5113       AIS_KindOfDimension KOD = Handle(AIS_Relation)::DownCast (curio)->KindOfDimension();
5114       if ((dimension_status==0 && KOD == AIS_KOD_NONE)||
5115           (dimension_status==1 && KOD != AIS_KOD_NONE))
5116         TheAISContext()->Display(curio,Standard_False);
5117     }
5118
5119   }
5120
5121   TheAISContext()->UpdateCurrentViewer();
5122   return 0;
5123 }
5124
5125 static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a)
5126 {
5127   ifstream s(a[1]);
5128   BRep_Builder builder;
5129   TopoDS_Shape shape;
5130   BRepTools::Read(shape, s, builder);
5131   DBRep::Set(a[1], shape);
5132   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
5133   Handle(AIS_Shape) ais = new AIS_Shape(shape);
5134   Ctx->Display(ais);
5135   return 0;
5136 }
5137
5138 //===============================================================================================
5139 //function : VBsdf
5140 //purpose  :
5141 //===============================================================================================
5142 static int VBsdf (Draw_Interpretor& theDi,
5143                   Standard_Integer  theArgsNb,
5144                   const char**      theArgVec)
5145 {
5146   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
5147   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5148   if (aView.IsNull()
5149    || aViewer.IsNull())
5150   {
5151     std::cerr << "No active viewer!\n";
5152     return 1;
5153   }
5154
5155   ViewerTest_CmdParser aCmd;
5156
5157   aCmd.AddDescription ("Adjusts parameters of material BSDF:");
5158   aCmd.AddOption ("print|echo|p", "Print BSDF");
5159
5160   aCmd.AddOption ("kd", "Weight of the Lambertian BRDF");
5161   aCmd.AddOption ("kr", "Weight of the reflection BRDF");
5162   aCmd.AddOption ("kt", "Weight of the transmission BTDF");
5163   aCmd.AddOption ("ks", "Weight of the glossy Blinn BRDF");
5164   aCmd.AddOption ("le", "Self-emitted radiance");
5165
5166   aCmd.AddOption ("fresnel|f", "Fresnel coefficients; Allowed fresnel formats are: Constant x, Schlick x y z, Dielectric x, Conductor x y");
5167
5168   aCmd.AddOption ("roughness|r",    "Roughness of material (Blinn's exponent)");
5169   aCmd.AddOption ("absorpCoeff|af", "Absorption coeff (only for transparent material)");
5170   aCmd.AddOption ("absorpColor|ac", "Absorption color (only for transparent material)");
5171
5172   aCmd.AddOption ("normalize|n", "Normalize BSDF coefficients");
5173
5174   aCmd.Parse (theArgsNb, theArgVec);
5175
5176   if (aCmd.HasOption ("help"))
5177   {
5178     theDi.PrintHelp (theArgVec[0]);
5179     return 0;
5180   }
5181
5182   TCollection_AsciiString aName (aCmd.Arg ("", 0).c_str());
5183
5184   // find object
5185   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
5186   if (!aMap.IsBound2 (aName) )
5187   {
5188     std::cerr << "Use 'vdisplay' before" << "\n";
5189     return 1;
5190   }
5191
5192   Handle(AIS_InteractiveObject) anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
5193   Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
5194   Graphic3d_BSDF aBSDF = aMaterial.BSDF();
5195
5196   if (aCmd.HasOption ("print"))
5197   {
5198     Graphic3d_Vec4 aFresnel = aBSDF.Fresnel.Serialize();
5199
5200     std::cout << "\n"
5201       << "Kd:               " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
5202       << "Kr:               " << aBSDF.Kr.r() << ", " << aBSDF.Kr.g() << ", " << aBSDF.Kr.b() << "\n"
5203       << "Kt:               " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
5204       << "Ks:               " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
5205       << "Le:               " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n"
5206       << "Fresnel:          ";
5207
5208     if (aFresnel.x() >= 0.f)
5209     {
5210       std::cout
5211         << "|Schlick| " << aFresnel.x() << ", " << aFresnel.y() << ", " << aFresnel.z() << "\n";
5212     }
5213     else if (aFresnel.x() >= -1.5f)
5214     {
5215       std::cout
5216         << "|Constant| " << aFresnel.z() << "\n";
5217     }
5218     else if (aFresnel.x() >= -2.5f)
5219     {
5220       std::cout
5221         << "|Conductor| " << aFresnel.y() << ", " << aFresnel.z() << "\n";
5222     }
5223     else
5224     {
5225       std::cout
5226         << "|Dielectric| " << aFresnel.y() << "\n";
5227     }
5228
5229
5230     std::cout 
5231       << "Roughness:        " << aBSDF.Roughness           << "\n"
5232       << "Absorption coeff: " << aBSDF.AbsorptionCoeff     << "\n"
5233       << "Absorption color: " << aBSDF.AbsorptionColor.r() << ", "
5234                               << aBSDF.AbsorptionColor.g() << ", "
5235                               << aBSDF.AbsorptionColor.b() << "\n";
5236
5237     return 0;
5238   }
5239
5240   if (aCmd.HasOption ("roughness", 1, Standard_True))
5241   {
5242     aCmd.Arg ("roughness", 0);
5243     aBSDF.Roughness = aCmd.ArgFloat ("roughness");
5244   }
5245
5246   if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
5247   {
5248     aBSDF.AbsorptionCoeff = aCmd.ArgFloat ("absorpCoeff");
5249   }
5250
5251   if (aCmd.HasOption ("absorpColor", 3, Standard_True))
5252   {
5253     aBSDF.AbsorptionColor = aCmd.ArgVec3f ("absorpColor");
5254   }
5255
5256   if (aCmd.HasOption ("kd", 3))
5257   {
5258     aBSDF.Kd = aCmd.ArgVec3f ("kd");
5259   }
5260   else if (aCmd.HasOption ("kd", 1, Standard_True))
5261   {
5262     aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
5263   }
5264
5265   if (aCmd.HasOption ("kr", 3))
5266   {
5267     aBSDF.Kr = aCmd.ArgVec3f ("kr");
5268   }
5269   else if (aCmd.HasOption ("kr", 1, Standard_True))
5270   {
5271     aBSDF.Kr = Graphic3d_Vec3 (aCmd.ArgFloat ("kr"));
5272   }
5273
5274   if (aCmd.HasOption ("kt", 3))
5275   {
5276     aBSDF.Kt = aCmd.ArgVec3f ("kt");
5277   }
5278   else if (aCmd.HasOption ("kt", 1, Standard_True))
5279   {
5280     aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
5281   }
5282
5283   if (aCmd.HasOption ("ks", 3))
5284   {
5285     aBSDF.Ks = aCmd.ArgVec3f ("ks");
5286   }
5287   else if (aCmd.HasOption ("ks", 1, Standard_True))
5288   {
5289     aBSDF.Ks = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
5290   }
5291
5292   if (aCmd.HasOption ("le", 3))
5293   {
5294     aBSDF.Le = aCmd.ArgVec3f ("le");
5295   }
5296   else if (aCmd.HasOption ("le", 1, Standard_True))
5297   {
5298     aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
5299   }
5300
5301   const std::string aFresnelErrorMessage =
5302     "Error! Wrong Fresnel type. Allowed types are: Constant x, Schlick x y z, Dielectric x, Conductor x y.\n";
5303
5304   if (aCmd.HasOption ("fresnel", 4)) // Schlick: type, x, y ,z
5305   {
5306     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5307     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5308
5309     if (aFresnelType == "schlick")
5310     {
5311       aBSDF.Fresnel = Graphic3d_Fresnel::CreateSchlick (
5312         Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
5313                         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())),
5314                         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 3).c_str()))));
5315     }
5316     else
5317     {
5318       std::cout << aFresnelErrorMessage;
5319     }
5320   }
5321   else if (aCmd.HasOption ("fresnel", 3)) // Conductor: type, x, y
5322   {
5323     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5324     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5325
5326     if (aFresnelType == "conductor")
5327     {
5328       aBSDF.Fresnel = Graphic3d_Fresnel::CreateConductor (
5329         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
5330         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())));
5331     }
5332     else
5333     {
5334       std::cout << aFresnelErrorMessage;
5335     }
5336   }
5337   else if (aCmd.HasOption ("fresnel", 2)) // Dielectric, Constant: type, x
5338   {
5339     std::string aFresnelType = aCmd.Arg ("fresnel", 0);
5340     std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
5341
5342     if (aFresnelType == "dielectric")
5343     {
5344       aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (
5345         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
5346     }
5347     else if (aFresnelType == "constant")
5348     {
5349       aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (
5350         static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
5351     }
5352     else
5353     {
5354       std::cout << aFresnelErrorMessage;
5355     }
5356   }
5357
5358   if (aCmd.HasOption ("normalize"))
5359   {
5360     aBSDF.Normalize();
5361   }
5362
5363   aMaterial.SetBSDF (aBSDF);
5364   anIObj->SetMaterial (aMaterial);
5365
5366   aView->Redraw();
5367
5368   return 0;
5369 }
5370
5371 //==============================================================================
5372 //function : VLoadSelection
5373 //purpose  : Adds given objects to map of AIS and loads selection primitives for them
5374 //==============================================================================
5375 static Standard_Integer VLoadSelection (Draw_Interpretor& /*theDi*/,
5376                                         Standard_Integer theArgNb,
5377                                         const char** theArgVec)
5378 {
5379   if (theArgNb < 2)
5380   {
5381     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5382     return 1;
5383   }
5384
5385   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5386   if (aCtx.IsNull())
5387   {
5388     ViewerTest::ViewerInit();
5389     aCtx = ViewerTest::GetAISContext();
5390   }
5391
5392   // Parse input arguments
5393   TColStd_SequenceOfAsciiString aNamesOfIO;
5394   Standard_Boolean isLocal = Standard_False;
5395   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5396   {
5397     const TCollection_AsciiString aName     = theArgVec[anArgIter];
5398     TCollection_AsciiString       aNameCase = aName;
5399     aNameCase.LowerCase();
5400     if (aNameCase == "-local")
5401     {
5402       isLocal = Standard_True;
5403     }
5404     else
5405     {
5406       aNamesOfIO.Append (aName);
5407     }
5408   }
5409
5410   if (aNamesOfIO.IsEmpty())
5411   {
5412     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5413     return 1;
5414   }
5415
5416   // Prepare context
5417   if (isLocal && !aCtx->HasOpenedContext())
5418   {
5419     aCtx->OpenLocalContext (Standard_False);
5420   }
5421   else if (!isLocal && aCtx->HasOpenedContext())
5422   {
5423     aCtx->CloseAllContexts (Standard_False);
5424   }
5425
5426   // Load selection of interactive objects
5427   for (Standard_Integer anIter = 1; anIter <= aNamesOfIO.Length(); ++anIter)
5428   {
5429     const TCollection_AsciiString& aName = aNamesOfIO.Value (anIter);
5430
5431     Handle(AIS_InteractiveObject) aShape;
5432     if (GetMapOfAIS().IsBound2 (aName))
5433       aShape = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
5434     else
5435       aShape = GetAISShapeFromName (aName.ToCString());
5436
5437     if (!aShape.IsNull())
5438     {
5439       if (!GetMapOfAIS().IsBound2 (aName))
5440       {
5441         GetMapOfAIS().Bind (aShape, aName);
5442       }
5443
5444       aCtx->Load (aShape, -1, Standard_False);
5445       aCtx->Activate (aShape, aShape->GlobalSelectionMode(), Standard_True);
5446     }
5447   }
5448
5449   return 0;
5450 }
5451
5452 //==============================================================================
5453 //function : VAutoActivateSelection
5454 //purpose  : Activates or deactivates auto computation of selection
5455 //==============================================================================
5456 static int VAutoActivateSelection (Draw_Interpretor& theDi,
5457                                    Standard_Integer theArgNb,
5458                                    const char** theArgVec)
5459 {
5460
5461   if (theArgNb > 2)
5462   {
5463     std::cerr << theArgVec[0] << "Error: wrong number of arguments.\n";
5464     return 1;
5465   }
5466
5467   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5468   if (aCtx.IsNull())
5469   {
5470     ViewerTest::ViewerInit();
5471     aCtx = ViewerTest::GetAISContext();
5472   }
5473
5474   if (theArgNb == 1)
5475   {
5476     TCollection_AsciiString aSelActivationString;
5477     if (aCtx->GetAutoActivateSelection())
5478     {
5479       aSelActivationString.Copy ("ON");
5480     }
5481     else
5482     {
5483       aSelActivationString.Copy ("OFF");
5484     }
5485
5486     theDi << "Auto activation of selection is: " << aSelActivationString << "\n";
5487   }
5488   else
5489   {
5490     Standard_Boolean toActivate = Draw::Atoi (theArgVec[1]);
5491     aCtx->SetAutoActivateSelection (toActivate);
5492   }
5493
5494   return 0;
5495 }
5496
5497 //==============================================================================
5498 //function : ViewerTest::Commands
5499 //purpose  : Add all the viewer command in the Draw_Interpretor
5500 //==============================================================================
5501
5502 void ViewerTest::Commands(Draw_Interpretor& theCommands)
5503 {
5504   ViewerTest::ViewerCommands(theCommands);
5505   ViewerTest::RelationCommands(theCommands);
5506   ViewerTest::ObjectCommands(theCommands);
5507   ViewerTest::FilletCommands(theCommands);
5508   ViewerTest::OpenGlCommands(theCommands);
5509
5510   const char *group = "AIS_Display";
5511
5512   // display
5513   theCommands.Add("visos",
5514       "visos [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]\n"
5515       "\tIf last 3 optional parameters are not set prints numbers of U-, V- isolines and IsoOnPlane.\n",
5516       __FILE__, visos, group);
5517
5518   theCommands.Add("vdisplay",
5519               "vdisplay [-noupdate|-update] [-local] [-mutable] [-neutral]"
5520       "\n\t\t:          [-trsfPers {pan|zoom|rotate|trihedron|full|none}=none] [-trsfPersPos X Y [Z]] [-3d|-2d|-2dTopDown]"
5521       "\n\t\t:          [-dispMode mode] [-highMode mode]"
5522       "\n\t\t:          [-layer index] [-top|-topmost|-overlay|-underlay]"
5523       "\n\t\t:          [-redisplay]"
5524       "\n\t\t:          name1 [name2] ... [name n]"
5525       "\n\t\t: Displays named objects."
5526       "\n\t\t: Option -local enables displaying of objects in local"
5527       "\n\t\t: selection context. Local selection context will be opened"
5528       "\n\t\t: if there is not any."
5529       "\n\t\t:  -noupdate    suppresses viewer redraw call."
5530       "\n\t\t:  -mutable     enables optimizations for mutable objects."
5531       "\n\t\t:  -neutral     draws objects in main viewer."
5532       "\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."
5533       "\n\t\t:  -top         draws objects on top of main presentations but below topmost."
5534       "\n\t\t:  -topmost     draws in overlay for 3D presentations with independent Depth."
5535       "\n\t\t:  -overlay     draws objects in overlay for 2D presentations (On-Screen-Display)."
5536       "\n\t\t:  -underlay    draws objects in underlay for 2D presentations (On-Screen-Display)."
5537       "\n\t\t:  -selectable|-noselect controls selection of objects."
5538       "\n\t\t:  -trsfPers    sets a transform persistence flags. Flag 'full' is pan, zoom and rotate."
5539       "\n\t\t:  -trsfPersPos sets an anchor point for transform persistence."
5540       "\n\t\t:  -2d|-2dTopDown displays object in screen coordinates."
5541       "\n\t\t:  -dispmode sets display mode for objects."
5542       "\n\t\t:  -highmode sets hilight mode for objects."
5543       "\n\t\t:  -redisplay recomputes presentation of objects.",
5544       __FILE__, VDisplay2, group);
5545
5546   theCommands.Add ("vupdate",
5547       "vupdate name1 [name2] ... [name n]"
5548       "\n\t\t: Updates named objects in interactive context",
5549       __FILE__, VUpdate, group);
5550
5551   theCommands.Add("verase",
5552       "verase [-noupdate|-update] [-local] [name1] ...  [name n]"
5553       "\n\t\t: Erases selected or named objects."
5554       "\n\t\t: If there are no selected or named objects the whole viewer is erased."
5555       "\n\t\t: Option -local enables erasing of selected or named objects without"
5556       "\n\t\t: closing local selection context.",
5557       __FILE__, VErase, group);
5558
5559   theCommands.Add("vremove",
5560       "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ...  [name n]"
5561       "or vremove [-context] -all to remove all objects"
5562       "\n\t\t: Removes selected or named objects."
5563       "\n\t\t  If -context is in arguments, the objects are not deleted"
5564       "\n\t\t  from the map of objects and names."
5565       "\n\t\t: Option -local enables removing of selected or named objects without"
5566       "\n\t\t: closing local selection context. Empty local selection context will be"
5567       "\n\t\t: closed."
5568       "\n\t\t: Option -noupdate suppresses viewer redraw call."
5569       "\n\t\t: Option -noinfo suppresses displaying the list of removed objects.",
5570       __FILE__, VRemove, group);
5571
5572   theCommands.Add("vdonly",
5573                   "vdonly [-noupdate|-update] [name1] ...  [name n]"
5574       "\n\t\t: Displays only selected or named objects",
5575                   __FILE__,VDonly2,group);
5576
5577   theCommands.Add("vdisplayall",
5578       "vidsplayall [-local]"
5579       "\n\t\t: Displays all erased interactive objects (see vdir and vstate)."
5580       "\n\t\t: Option -local enables displaying of the objects in local"
5581       "\n\t\t: selection context.",
5582       __FILE__, VDisplayAll, group);
5583
5584   theCommands.Add("veraseall",
5585       "veraseall [-local]"
5586       "\n\t\t: Erases all objects displayed in the viewer."
5587       "\n\t\t: Option -local enables erasing of the objects in local"
5588       "\n\t\t: selection context.",
5589       __FILE__, VErase, group);
5590
5591   theCommands.Add("verasetype",
5592       "verasetype <Type>"
5593       "\n\t\t: Erase all the displayed objects of one given kind (see vtypes)",
5594       __FILE__, VEraseType, group);
5595   theCommands.Add("vbounding",
5596               "vbounding [-noupdate|-update] [-mode] name1 [name2 [...]]"
5597       "\n\t\t:           [-print] [-hide]"
5598       "\n\t\t: Temporarily display bounding box of specified Interactive"
5599       "\n\t\t: Objects, or print it to console if -print is specified."
5600       "\n\t\t: Already displayed box might be hidden by -hide option.",
5601                   __FILE__,VBounding,group);
5602
5603   theCommands.Add("vdisplaytype",
5604                   "vdisplaytype        : vdisplaytype <Type> <Signature> \n\t display all the objects of one given kind (see vtypes) which are stored the AISContext ",
5605                   __FILE__,VDisplayType,group);
5606
5607   theCommands.Add("vdisplaymode",
5608                   "vdispmode       : vdispmode  [name] mode(1,2,..) : no name -> on selected objects ",
5609                   __FILE__,VDispMode,group);
5610
5611   theCommands.Add("verasemode",
5612                   "verasemode      : verasemode [name] mode(1,2,..) : no name -> on selected objects",
5613                   __FILE__,VDispMode,group);
5614
5615   theCommands.Add("vsetdispmode",
5616                   "vsetdispmode [name] mode(1,2,..)"
5617       "\n\t\t: Sets display mode for all, selected or named objects.",
5618                   __FILE__,VDispMode,group);
5619
5620   theCommands.Add("vunsetdispmode",
5621                   "vunsetdispmode [name]"
5622       "\n\t\t: Unsets custom display mode for selected or named objects.",
5623                   __FILE__,VDispMode,group);
5624
5625   theCommands.Add("vdir",
5626                   "Lists all objects displayed in 3D viewer",
5627                   __FILE__,VDir,group);
5628
5629 #ifdef HAVE_FREEIMAGE
5630   #define DUMP_FORMATS "{png|bmp|jpg|gif}"
5631 #else
5632   #define DUMP_FORMATS "{ppm}"
5633 #endif
5634   theCommands.Add("vdump",
5635               "vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
5636       "\n\t\t:       [-buffer rgb|rgba|depth=rgb]"
5637       "\n\t\t:       [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
5638       "\n\t\t: Dumps content of the active view into image file",
5639                   __FILE__,VDump,group);
5640
5641   theCommands.Add("vsub",      "vsub 0/1 (off/on) [obj]        : Subintensity(on/off) of selected objects",
5642                   __FILE__,VSubInt,group);
5643
5644   theCommands.Add("vaspects",
5645               "vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults]"
5646       "\n\t\t:          [-setVisibility 0|1]"
5647       "\n\t\t:          [-setColor ColorName] [-setcolor R G B] [-unsetColor]"
5648       "\n\t\t:          [-setMaterial MatName] [-unsetMaterial]"
5649       "\n\t\t:          [-setTransparency Transp] [-unsetTransparency]"
5650       "\n\t\t:          [-setWidth LineWidth] [-unsetWidth]"
5651       "\n\t\t:          [-setLineType {solid|dash|dot|dotDash}] [-unsetLineType]"
5652       "\n\t\t:          [-freeBoundary {off/on | 0/1}]"
5653       "\n\t\t:          [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]"
5654       "\n\t\t:          [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]"
5655       "\n\t\t:          [-subshapes subname1 [subname2 [...]]]"
5656       "\n\t\t:          [-isoontriangulation 0|1]"
5657       "\n\t\t:          [-setMaxParamValue {value}]"
5658       "\n\t\t:          [-setSensitivity {selection_mode} {value}]"
5659       "\n\t\t: Manage presentation properties of all, selected or named objects."
5660       "\n\t\t: When -subshapes is specified than following properties will be"
5661       "\n\t\t: assigned to specified sub-shapes."
5662       "\n\t\t: When -defaults is specified than presentation properties will be"
5663       "\n\t\t: assigned to all objects that have not their own specified properties"
5664       "\n\t\t: and to all objects to be displayed in the future."
5665       "\n\t\t: If -defaults is used there should not be any objects' names and -subshapes specifier.",
5666                   __FILE__,VAspects,group);
5667
5668   theCommands.Add("vsetcolor",
5669       "vsetcolor [-noupdate|-update] [name] ColorName"
5670       "\n\t\t: Sets color for all, selected or named objects."
5671       "\n\t\t: Alias for vaspects -setcolor [name] ColorName.",
5672                   __FILE__,VAspects,group);
5673
5674   theCommands.Add("vunsetcolor",
5675                   "vunsetcolor [-noupdate|-update] [name]"
5676       "\n\t\t: Resets color for all, selected or named objects."
5677       "\n\t\t: Alias for vaspects -unsetcolor [name].",
5678                   __FILE__,VAspects,group);
5679
5680   theCommands.Add("vsettransparency",
5681                   "vsettransparency [-noupdate|-update] [name] Coefficient"
5682       "\n\t\t: Sets transparency for all, selected or named objects."
5683       "\n\t\t: The Coefficient may be between 0.0 (opaque) and 1.0 (fully transparent)."
5684       "\n\t\t: Alias for vaspects -settransp [name] Coefficient.",
5685                   __FILE__,VAspects,group);
5686
5687   theCommands.Add("vunsettransparency",
5688                   "vunsettransparency [-noupdate|-update] [name]"
5689       "\n\t\t: Resets transparency for all, selected or named objects."
5690       "\n\t\t: Alias for vaspects -unsettransp [name].",
5691                   __FILE__,VAspects,group);
5692
5693   theCommands.Add("vsetmaterial",
5694                   "vsetmaterial [-noupdate|-update] [name] MaterialName"
5695       "\n\t\t: Alias for vaspects -setmaterial [name] MaterialName.",
5696                   __FILE__,VAspects,group);
5697
5698   theCommands.Add("vunsetmaterial",
5699                   "vunsetmaterial [-noupdate|-update] [name]"
5700       "\n\t\t: Alias for vaspects -unsetmaterial [name].",
5701                   __FILE__,VAspects,group);
5702
5703   theCommands.Add("vsetwidth",
5704                   "vsetwidth [-noupdate|-update] [name] width(0->10)"
5705       "\n\t\t: Alias for vaspects -setwidth [name] width.",
5706                   __FILE__,VAspects,group);
5707
5708   theCommands.Add("vunsetwidth",
5709                   "vunsetwidth [-noupdate|-update] [name]"
5710       "\n\t\t: Alias for vaspects -unsetwidth [name] width.",
5711                   __FILE__,VAspects,group);
5712
5713   theCommands.Add("vsetinteriorstyle",
5714                   "vsetinteriorstyle [-noupdate|-update] [name] style"
5715       "\n\t\t: Where style is: 0 = EMPTY, 1 = HOLLOW, 2 = HATCH, 3 = SOLID, 4 = HIDDENLINE.",
5716                   __FILE__,VSetInteriorStyle,group);
5717
5718   theCommands.Add("vsensdis",
5719       "vsensdis : Display active entities (sensitive entities of one of the standard types corresponding to active selection modes)."
5720       "\n\t\t: Standard entity types are those defined in Select3D package:"
5721       "\n\t\t: - sensitive box"
5722       "\n\t\t: - sensitive face"
5723       "\n\t\t: - sensitive curve"
5724       "\n\t\t: - sensitive segment"
5725       "\n\t\t: - sensitive circle"
5726       "\n\t\t: - sensitive point"
5727       "\n\t\t: - sensitive triangulation"
5728       "\n\t\t: - sensitive triangle"
5729       "\n\t\t: Custom(application - defined) sensitive entity types are not processed by this command.",
5730       __FILE__,VDispSensi,group);
5731
5732   theCommands.Add("vsensera",
5733       "vsensera : erase active entities",
5734       __FILE__,VClearSensi,group);
5735
5736   theCommands.Add("vselprecision",
5737                   "vselprecision [-unset] [tolerance_value]"
5738                   "\n\t\t  Manages selection precision or prints current value if no parameter is passed."
5739                   "\n\t\t  -unset - restores default selection tolerance behavior, based on individual entity tolerance",
5740                   __FILE__,VSelPrecision,group);
5741
5742   theCommands.Add("vperf",
5743       "vperf: vperf  ShapeName 1/0(Transfo/Location) 1/0(Primitives sensibles ON/OFF)"
5744       "\n\t\t: Tests the animation of an object along a predefined trajectory.",
5745       __FILE__,VPerf,group);
5746
5747   theCommands.Add("vanimation",
5748                   "vanimation CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile",
5749                   __FILE__,VAnimation,group);
5750
5751   theCommands.Add("vsetshading",
5752       "vsetshading  : vsetshading name Quality(default=0.0008) "
5753       "\n\t\t: Sets deflection coefficient that defines the quality of the shape\92s representation in the shading mode.",
5754       __FILE__,VShading,group);
5755
5756   theCommands.Add("vunsetshading",
5757       "vunsetshading :vunsetshading name "
5758       "\n\t\t: Sets default deflection coefficient (0.0008) that defines the quality of the shape\92s representation in the shading mode.",
5759       __FILE__,VShading,group);
5760
5761   theCommands.Add ("vtexture",
5762                    "\n'vtexture NameOfShape [TextureFile | IdOfTexture]\n"
5763                    "                         [-scale u v]  [-scale off]\n"
5764                    "                         [-origin u v] [-origin off]\n"
5765                    "                         [-repeat u v] [-repeat off]\n"
5766                    "                         [-modulate {on | off}]"
5767                    "                         [-default]'\n"
5768                    " The texture can be specified by filepath or as ID (0<=IdOfTexture<=20)\n"
5769                    " specifying one of the predefined textures.\n"
5770                    " The options are: \n"
5771                    "  -scale u v : enable texture scaling and set scale factors\n"
5772                    "  -scale off : disable texture scaling\n"
5773                    "  -origin u v : enable texture origin positioning and set the origin\n"
5774                    "  -origin off : disable texture origin positioning\n"
5775                    "  -repeat u v : enable texture repeat and set texture coordinate scaling\n"
5776                    "  -repeat off : disable texture repeat\n"
5777                    "  -modulate {on | off} : enable or disable texture modulation\n"
5778                    "  -default : sets texture mapping default parameters\n"
5779                    "or 'vtexture NameOfShape' if you want to disable texture mapping\n"
5780                    "or 'vtexture NameOfShape ?' to list available textures\n",
5781                     __FILE__, VTexture, group);
5782
5783   theCommands.Add("vtexscale",
5784                   "'vtexscale  NameOfShape ScaleU ScaleV' \n \
5785                    or 'vtexscale NameOfShape ScaleUV' \n \
5786                    or 'vtexscale NameOfShape' to disable scaling\n ",
5787                   __FILE__,VTexture,group);
5788
5789   theCommands.Add("vtexorigin",
5790                   "'vtexorigin NameOfShape UOrigin VOrigin' \n \
5791                    or 'vtexorigin NameOfShape UVOrigin' \n \
5792                    or 'vtexorigin NameOfShape' to disable origin positioning\n ",
5793                   __FILE__,VTexture,group);
5794
5795   theCommands.Add("vtexrepeat",
5796                   "'vtexrepeat  NameOfShape URepeat VRepeat' \n \
5797                    or 'vtexrepeat NameOfShape UVRepeat \n \
5798                    or 'vtexrepeat NameOfShape' to disable texture repeat \n ",
5799                   VTexture,group);
5800
5801   theCommands.Add("vtexdefault",
5802                   "'vtexdefault NameOfShape' to set texture mapping default parameters \n",
5803                   VTexture,group);
5804
5805   theCommands.Add("vsetam",
5806       "vsetam [shapename] mode"
5807       "\n\t\t: Activates selection mode for all selected or named shapes."
5808       "\n\t\t: Mod can be:"
5809       "\n\t\t:   0 - for shape itself" 
5810       "\n\t\t:   1 - vertices"
5811       "\n\t\t:   2 - edges"
5812       "\n\t\t:   3 - wires"
5813       "\n\t\t:   4 - faces"
5814       "\n\t\t:   5 - shells"
5815       "\n\t\t:   6 - solids"
5816       "\n\t\t:   7 - compounds"
5817       __FILE__,VActivatedMode,group);
5818
5819   theCommands.Add("vunsetam",
5820       "vunsetam : Deactivates all selection modes for all shapes.",
5821       __FILE__,VActivatedMode,group);
5822
5823   theCommands.Add("vstate",
5824       "vstate [-entities] [-hasSelected] [name1] ... [nameN]"
5825       "\n\t\t: Reports show/hidden state for selected or named objects"
5826       "\n\t\t:   -entities - print low-level information about detected entities"
5827       "\n\t\t:   -hasSelected - prints 1 if context has selected shape and 0 otherwise",
5828                   __FILE__,VState,group);
5829
5830   theCommands.Add("vpickshapes",
5831                   "vpickshape subtype(VERTEX,EDGE,WIRE,FACE,SHELL,SOLID) [name1 or .] [name2 or .] [name n or .]",
5832                   __FILE__,VPickShape,group);
5833
5834   theCommands.Add("vtypes",
5835                   "vtypes : list of known types and signatures in AIS - To be Used in vpickobject command for selection with filters",
5836                   VIOTypes,group);
5837
5838   theCommands.Add("vr",
5839       "vr filename"
5840       "\n\t\t: Reads shape from BREP-format file and displays it in the viewer. ",
5841                   __FILE__,vr, group);
5842
5843   theCommands.Add("vpickselected", "vpickselected [name]: extract selected shape.",
5844     __FILE__, VPickSelected, group);
5845
5846   theCommands.Add ("vloadselection",
5847     "vloadselection [-context] [name1] ... [nameN] : allows to load selection"
5848     "\n\t\t: primitives for the shapes with names given without displaying them."
5849     "\n\t\t:   -local - open local context before selection computation",
5850     __FILE__, VLoadSelection, group);
5851
5852   theCommands.Add ("vautoactivatesel",
5853     "vautoactivatesel [0|1] : manage or display the option to automatically"
5854     "\n\t\t: activate selection for newly displayed objects"
5855     "\n\t\t:   [0|1] - turn off | on auto activation of selection",
5856     __FILE__, VAutoActivateSelection, group);
5857
5858   theCommands.Add("vbsdf", "vbsdf [name] [options]"
5859     "\nAdjusts parameters of material BSDF:"
5860     "\n    -help : Shows this message"
5861     "\n    -print : Print BSDF"
5862     "\n    -kd : Weight of the Lambertian BRDF"
5863     "\n    -kr : Weight of the reflection BRDF"
5864     "\n    -kt : Weight of the transmission BTDF"
5865     "\n    -ks : Weight of the glossy Blinn BRDF"
5866     "\n    -le : Self-emitted radiance"
5867     "\n    -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
5868     "\n               Schlick x y z, Dielectric x, Conductor x y"
5869     "\n    -roughness : Roughness of material (Blinn's exponent)"
5870     "\n    -absorpcoeff : Absorption coefficient (only for transparent material)"
5871     "\n    -absorpcolor : Absorption color (only for transparent material)"
5872     "\n    -normalize : Normalize BSDF coefficients",
5873     __FILE__, VBsdf, group);
5874
5875 }
5876
5877 //=====================================================================
5878 //========================= for testing Draft and Rib =================
5879 //=====================================================================
5880 #include <BRepOffsetAPI_MakeThickSolid.hxx>
5881 #include <DBRep.hxx>
5882 #include <TopoDS_Face.hxx>
5883 #include <gp_Pln.hxx>
5884 #include <AIS_KindOfSurface.hxx>
5885 #include <BRepOffsetAPI_DraftAngle.hxx>
5886 #include <Precision.hxx>
5887 #include <BRepAlgo.hxx>
5888 #include <OSD_Environment.hxx>
5889 #include <DrawTrSurf.hxx>
5890 //#include <DbgTools.hxx>
5891 //#include <FeatAlgo_MakeLinearForm.hxx>
5892
5893
5894
5895
5896 //=======================================================================
5897 //function : IsValid
5898 //purpose  :
5899 //=======================================================================
5900 static Standard_Boolean IsValid(const TopTools_ListOfShape& theArgs,
5901                                 const TopoDS_Shape& theResult,
5902                                 const Standard_Boolean closedSolid,
5903                                 const Standard_Boolean GeomCtrl)
5904 {
5905   OSD_Environment check ("DONT_SWITCH_IS_VALID") ;
5906   TCollection_AsciiString checkValid = check.Value();
5907   Standard_Boolean ToCheck = Standard_True;
5908   if (!checkValid.IsEmpty()) {
5909 #ifdef OCCT_DEBUG
5910     cout <<"DONT_SWITCH_IS_VALID positionnee a :"<<checkValid.ToCString()<<"\n";
5911 #endif
5912     if ( checkValid=="true" || checkValid=="TRUE" ) {
5913       ToCheck= Standard_False;
5914     }
5915   } else {
5916 #ifdef OCCT_DEBUG
5917     cout <<"DONT_SWITCH_IS_VALID non positionne"<<"\n";
5918 #endif
5919   }
5920   Standard_Boolean IsValid = Standard_True;
5921   if (ToCheck)
5922     IsValid = BRepAlgo::IsValid(theArgs,theResult,closedSolid,GeomCtrl) ;
5923   return IsValid;
5924
5925 }
5926
5927 //===============================================================================
5928 // TDraft : test draft, uses AIS Viewer
5929 // Solid Face Plane Angle  Reverse
5930 //===============================================================================
5931 static Standard_Integer TDraft(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5932 {
5933   if (argc < 5) return 1;
5934 // argv[1] - TopoDS_Shape Solid
5935 // argv[2] - TopoDS_Shape Face
5936 // argv[3] - TopoDS_Shape Plane
5937 // argv[4] - Standard_Real Angle
5938 // argv[5] - Standard_Integer Reverse
5939
5940 //  Sprintf(prefix, argv[1]);
5941   Standard_Real anAngle = 0;
5942   Standard_Boolean Rev = Standard_False;
5943   Standard_Integer rev = 0;
5944   TopoDS_Shape Solid  = GetShapeFromName(argv[1]);
5945   TopoDS_Shape face   = GetShapeFromName(argv[2]);
5946   TopoDS_Face Face    = TopoDS::Face(face);
5947   TopoDS_Shape Plane  = GetShapeFromName(argv[3]);
5948   if (Plane.IsNull ()) {
5949     di << "TEST : Plane is NULL" << "\n";
5950     return 1;
5951   }
5952   anAngle = Draw::Atof(argv[4]);
5953   anAngle = 2*M_PI * anAngle / 360.0;
5954   gp_Pln aPln;
5955   Handle( Geom_Surface )aSurf;
5956   AIS_KindOfSurface aSurfType;
5957   Standard_Real Offset;
5958   gp_Dir aDir;
5959   if(argc > 4) { // == 5
5960     rev = Draw::Atoi(argv[5]);
5961     Rev = (rev)? Standard_True : Standard_False;
5962   }
5963
5964   TopoDS_Face face2 = TopoDS::Face(Plane);
5965   if(!AIS::GetPlaneFromFace(face2, aPln, aSurf, aSurfType, Offset))
5966     {
5967       di << "TEST : Can't find plane" << "\n";
5968       return 1;
5969     }
5970
5971   aDir = aPln.Axis().Direction();
5972   if (!aPln.Direct())
5973     aDir.Reverse();
5974   if (Plane.Orientation() == TopAbs_REVERSED)
5975     aDir.Reverse();
5976   di << "TEST : gp::Resolution() = " << gp::Resolution() << "\n";
5977
5978   BRepOffsetAPI_DraftAngle Draft (Solid);
5979
5980   if(Abs(anAngle)< Precision::Angular()) {
5981     di << "TEST : NULL angle" << "\n";
5982     return 1;}
5983
5984   if(Rev) anAngle = - anAngle;
5985   Draft.Add (Face, aDir, anAngle, aPln);
5986   Draft.Build ();
5987   if (!Draft.IsDone())  {
5988     di << "TEST : Draft Not DONE " << "\n";
5989     return 1;
5990   }
5991   TopTools_ListOfShape Larg;
5992   Larg.Append(Solid);
5993   if (!IsValid(Larg,Draft.Shape(),Standard_True,Standard_False)) {
5994     di << "TEST : DesignAlgo returns Not valid" << "\n";
5995     return 1;
5996   }
5997
5998   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
5999   Handle(AIS_Shape) ais = new AIS_Shape(Draft.Shape());
6000
6001   if ( !ais.IsNull() ) {
6002     ais->SetColor(DEFAULT_COLOR);
6003     ais->SetMaterial(DEFAULT_MATERIAL);
6004     // Display the AIS_Shape without redraw
6005     Ctx->Display(ais, Standard_False);
6006
6007     const char *Name = "draft1";
6008     Standard_Boolean IsBound = GetMapOfAIS().IsBound2(Name);
6009     if (IsBound) {
6010       Handle(AIS_InteractiveObject) an_object =
6011         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(Name));
6012       if (!an_object.IsNull()) {
6013         Ctx->Remove(an_object,
6014                     Standard_True) ;
6015         GetMapOfAIS().UnBind2(Name) ;
6016       }
6017     }
6018     GetMapOfAIS().Bind(ais, Name);
6019 //  DBRep::Set("draft", ais->Shape());
6020   }
6021   Ctx->Display(ais, Standard_True);
6022   return 0;
6023 }
6024
6025 //==============================================================================
6026 //function : splitParameter
6027 //purpose  : Split parameter string to parameter name and parameter value
6028 //==============================================================================
6029 Standard_Boolean ViewerTest::SplitParameter (const TCollection_AsciiString& theString,
6030                                              TCollection_AsciiString&       theName,
6031                                              TCollection_AsciiString&       theValue)
6032 {
6033   Standard_Integer aParamNameEnd = theString.FirstLocationInSet ("=", 1, theString.Length());
6034
6035   if (aParamNameEnd == 0)
6036   {
6037     return Standard_False;
6038   }
6039
6040   TCollection_AsciiString aString (theString);
6041   if (aParamNameEnd != 0)
6042   {
6043     theValue = aString.Split (aParamNameEnd);
6044     aString.Split (aString.Length() - 1);
6045     theName = aString;
6046   }
6047
6048   return Standard_True;
6049 }
6050
6051 //============================================================================
6052 //  MyCommands
6053 //============================================================================
6054 void ViewerTest::MyCommands( Draw_Interpretor& theCommands)
6055 {
6056
6057   DrawTrSurf::BasicCommands(theCommands);
6058   const char* group = "Check Features Operations commands";
6059
6060   theCommands.Add("Draft","Draft    Solid Face Plane Angle Reverse",
6061                   __FILE__,
6062                   &TDraft,group); //Draft_Modification
6063 }
6064
6065 //==============================================================================
6066 // ViewerTest::Factory
6067 //==============================================================================
6068 void ViewerTest::Factory(Draw_Interpretor& theDI)
6069 {
6070   // definition of Viewer Command
6071   ViewerTest::Commands(theDI);
6072   ViewerTest::AviCommands(theDI);
6073
6074 #ifdef OCCT_DEBUG
6075       theDI << "Draw Plugin : OCC V2d & V3d commands are loaded" << "\n";
6076 #endif
6077 }
6078
6079 // Declare entry point PLUGINFACTORY
6080 DPLUGIN(ViewerTest)