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