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