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