dc613f95f76e1a936bf39dae05fc6afc8af08715
[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 #include <Standard_Stream.hxx>
18
19 #include <ViewerTest.hxx>
20 #include <ViewerTest_CmdParser.hxx>
21
22 #include <Draw.hxx>
23 #include <TopLoc_Location.hxx>
24 #include <TopTools_HArray1OfShape.hxx>
25 #include <TColStd_HArray1OfTransient.hxx>
26 #include <TColStd_SequenceOfAsciiString.hxx>
27 #include <TColStd_HSequenceOfAsciiString.hxx>
28 #include <TColStd_MapOfTransient.hxx>
29 #include <OSD_Timer.hxx>
30 #include <Geom_Axis2Placement.hxx>
31 #include <Geom_Axis1Placement.hxx>
32 #include <gp_Trsf.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <StdSelect_ShapeTypeFilter.hxx>
36 #include <AIS_ColoredShape.hxx>
37 #include <AIS_InteractiveObject.hxx>
38 #include <AIS_Trihedron.hxx>
39 #include <AIS_Axis.hxx>
40 #include <PrsDim.hxx>
41 #include <PrsDim_Relation.hxx>
42 #include <AIS_TypeFilter.hxx>
43 #include <AIS_SignatureFilter.hxx>
44 #include <AIS_ListOfInteractive.hxx>
45 #include <AIS_ListIteratorOfListOfInteractive.hxx>
46 #include <Aspect_InteriorStyle.hxx>
47 #include <Aspect_Window.hxx>
48 #include <Graphic3d_AspectFillArea3d.hxx>
49 #include <Graphic3d_AspectLine3d.hxx>
50 #include <Graphic3d_CStructure.hxx>
51 #include <Graphic3d_Texture2Dmanual.hxx>
52 #include <Graphic3d_GraphicDriver.hxx>
53 #include <Graphic3d_MediaTextureSet.hxx>
54 #include <Image_AlienPixMap.hxx>
55 #include <Message.hxx>
56 #include <OSD_File.hxx>
57 #include <Prs3d_Drawer.hxx>
58 #include <Prs3d_ShadingAspect.hxx>
59 #include <Prs3d_IsoAspect.hxx>
60 #include <Prs3d_PointAspect.hxx>
61 #include <Select3D_SensitiveWire.hxx>
62 #include <Select3D_SensitivePrimitiveArray.hxx>
63 #include <SelectMgr_EntityOwner.hxx>
64 #include <StdSelect_BRepOwner.hxx>
65 #include <StdSelect_ViewerSelector3d.hxx>
66 #include <TopTools_MapOfShape.hxx>
67 #include <ViewerTest_AutoUpdater.hxx>
68 #include <Aspect_XRSession.hxx>
69
70 #include <stdio.h>
71
72 #include <Draw_Interpretor.hxx>
73 #include <TCollection_AsciiString.hxx>
74 #include <Draw_PluginMacro.hxx>
75
76 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
77
78 #include <Quantity_Color.hxx>
79 #include <Quantity_NameOfColor.hxx>
80
81 #include <Graphic3d_NameOfMaterial.hxx>
82
83 #define DEFAULT_COLOR              Quantity_NOC_GOLDENROD
84 #define DEFAULT_FREEBOUNDARY_COLOR Quantity_NOC_GREEN
85 #define DEFAULT_MATERIAL           Graphic3d_NOM_BRASS
86
87 //=======================================================================
88 // function : GetColorFromName
89 // purpose  : get the Quantity_NameOfColor from a string
90 //=======================================================================
91
92 Quantity_NameOfColor ViewerTest::GetColorFromName (const Standard_CString theName)
93 {
94   Quantity_NameOfColor aColor = DEFAULT_COLOR;
95   Quantity_Color::ColorFromName (theName, aColor);
96   return aColor;
97 }
98
99 //=======================================================================
100 // function : ParseColor
101 // purpose  :
102 //=======================================================================
103 Standard_Integer ViewerTest::ParseColor (const Standard_Integer   theArgNb,
104                                          const char* const* const theArgVec,
105                                          Quantity_ColorRGBA&      theColor)
106 {
107   return Draw::ParseColor (theArgNb, theArgVec, theColor);
108 }
109
110 //=======================================================================
111 // function : ParseColor
112 // purpose  :
113 //=======================================================================
114 Standard_Integer ViewerTest::ParseColor (const Standard_Integer   theArgNb,
115                                          const char* const* const theArgVec,
116                                          Quantity_Color&          theColor)
117 {
118   return Draw::ParseColor (theArgNb, theArgVec, theColor);
119 }
120
121 //=======================================================================
122 //function : ParseOnOff
123 //purpose  :
124 //=======================================================================
125 Standard_Boolean ViewerTest::ParseOnOff (Standard_CString  theArg,
126                                          Standard_Boolean& theIsOn)
127 {
128   return Draw::ParseOnOff (theArg, theIsOn);
129 }
130
131 //=======================================================================
132 //function : GetSelectedShapes
133 //purpose  :
134 //=======================================================================
135 void ViewerTest::GetSelectedShapes (TopTools_ListOfShape& theSelectedShapes)
136 {
137   for (GetAISContext()->InitSelected(); GetAISContext()->MoreSelected(); GetAISContext()->NextSelected())
138   {
139     TopoDS_Shape aShape = GetAISContext()->SelectedShape();
140     if (!aShape.IsNull())
141     {
142       theSelectedShapes.Append (aShape);
143     }
144   }
145 }
146
147 //=======================================================================
148 //function : ParseLineType
149 //purpose  :
150 //=======================================================================
151 Standard_Boolean ViewerTest::ParseLineType (Standard_CString theArg,
152                                             Aspect_TypeOfLine& theType,
153                                             uint16_t& thePattern)
154 {
155   TCollection_AsciiString aTypeStr (theArg);
156   aTypeStr.LowerCase();
157   if (aTypeStr == "empty"
158    || aTypeStr == "-1")
159   {
160     theType = Aspect_TOL_EMPTY;
161     thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
162   }
163   else if (aTypeStr == "solid"
164         || aTypeStr == "0")
165   {
166     theType = Aspect_TOL_SOLID;
167     thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
168   }
169   else if (aTypeStr == "dot"
170         || aTypeStr == "2")
171   {
172     theType = Aspect_TOL_DOT;
173     thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
174   }
175   else if (aTypeStr == "dash"
176         || aTypeStr == "1")
177   {
178     theType = Aspect_TOL_DASH;
179     thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
180   }
181   else if (aTypeStr == "dotdash"
182         || aTypeStr == "3")
183   {
184     theType = Aspect_TOL_DOTDASH;
185     thePattern = Graphic3d_Aspects::DefaultLinePatternForType (theType);
186   }
187   else
188   {
189     if (aTypeStr.StartsWith ("0x"))
190     {
191       aTypeStr = aTypeStr.SubString (3, aTypeStr.Length());
192     }
193
194     if (aTypeStr.Length() != 4
195     || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (1)))
196     || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (2)))
197     || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (3)))
198     || !std::isxdigit (static_cast<unsigned char> (aTypeStr.Value (4))))
199     {
200       return Standard_False;
201     }
202
203     std::stringstream aStream;
204     aStream << std::setbase (16) << aTypeStr.ToCString();
205     if (aStream.fail())
206     {
207       return Standard_False;
208     }
209
210     Standard_Integer aNumber = -1;
211     aStream >> aNumber;
212     if (aStream.fail())
213     {
214       return Standard_False;
215     }
216
217     thePattern = (uint16_t )aNumber;
218     theType = Graphic3d_Aspects::DefaultLineTypeForPattern (thePattern);
219   }
220   return Standard_True;
221 }
222
223 //=======================================================================
224 //function : ParseMarkerType
225 //purpose  :
226 //=======================================================================
227 Standard_Boolean ViewerTest::ParseMarkerType (Standard_CString theArg,
228                                               Aspect_TypeOfMarker& theType,
229                                               Handle(Image_PixMap)& theImage)
230 {
231   theImage.Nullify();
232   TCollection_AsciiString aTypeStr (theArg);
233   aTypeStr.LowerCase();
234   if (aTypeStr == "empty")
235   {
236     theType = Aspect_TOM_EMPTY;
237   }
238   else if (aTypeStr == "point"
239         || aTypeStr == "dot"
240         || aTypeStr == ".")
241   {
242     theType = Aspect_TOM_POINT;
243   }
244   else if (aTypeStr == "plus"
245         || aTypeStr == "+")
246   {
247     theType = Aspect_TOM_PLUS;
248   }
249   else if (aTypeStr == "star"
250         || aTypeStr == "*")
251   {
252     theType = Aspect_TOM_STAR;
253   }
254   else if (aTypeStr == "cross"
255         || aTypeStr == "x")
256   {
257     theType = Aspect_TOM_X;
258   }
259   else if (aTypeStr == "circle"
260         || aTypeStr == "o")
261   {
262     theType = Aspect_TOM_O;
263   }
264   else if (aTypeStr == "pointincircle")
265   {
266     theType = Aspect_TOM_O_POINT;
267   }
268   else if (aTypeStr == "plusincircle")
269   {
270     theType = Aspect_TOM_O_PLUS;
271   }
272   else if (aTypeStr == "starincircle")
273   {
274     theType = Aspect_TOM_O_STAR;
275   }
276   else if (aTypeStr == "crossincircle"
277         || aTypeStr == "xcircle")
278   {
279     theType = Aspect_TOM_O_X;
280   }
281   else if (aTypeStr == "ring1")
282   {
283     theType = Aspect_TOM_RING1;
284   }
285   else if (aTypeStr == "ring2")
286   {
287     theType = Aspect_TOM_RING2;
288   }
289   else if (aTypeStr == "ring"
290         || aTypeStr == "ring3")
291   {
292     theType = Aspect_TOM_RING3;
293   }
294   else if (aTypeStr == "ball")
295   {
296     theType = Aspect_TOM_BALL;
297   }
298   else if (aTypeStr.IsIntegerValue())
299   {
300     const int aTypeInt = aTypeStr.IntegerValue();
301     if (aTypeInt < -1 || aTypeInt >= Aspect_TOM_USERDEFINED)
302     {
303       return Standard_False;
304     }
305     theType = (Aspect_TypeOfMarker )aTypeInt;
306   }
307   else
308   {
309     theType = Aspect_TOM_USERDEFINED;
310     Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
311     if (!anImage->Load (theArg))
312     {
313       return Standard_False;
314     }
315     if (anImage->Format() == Image_Format_Gray)
316     {
317       anImage->SetFormat (Image_Format_Alpha);
318     }
319     else if (anImage->Format() == Image_Format_GrayF)
320     {
321       anImage->SetFormat (Image_Format_AlphaF);
322     }
323     theImage = anImage;
324   }
325   return Standard_True;
326 }
327
328 //=======================================================================
329 //function : ParseShadingModel
330 //purpose  :
331 //=======================================================================
332 Standard_Boolean ViewerTest::ParseShadingModel (Standard_CString              theArg,
333                                                 Graphic3d_TypeOfShadingModel& theModel)
334 {
335   TCollection_AsciiString aTypeStr (theArg);
336   aTypeStr.LowerCase();
337   if (aTypeStr == "unlit"
338    || aTypeStr == "color"
339    || aTypeStr == "none")
340   {
341     theModel = Graphic3d_TOSM_UNLIT;
342   }
343   else if (aTypeStr == "flat"
344         || aTypeStr == "facet")
345   {
346     theModel = Graphic3d_TOSM_FACET;
347   }
348   else if (aTypeStr == "gouraud"
349         || aTypeStr == "vertex"
350         || aTypeStr == "vert")
351   {
352     theModel = Graphic3d_TOSM_VERTEX;
353   }
354   else if (aTypeStr == "phong"
355         || aTypeStr == "fragment"
356         || aTypeStr == "frag"
357         || aTypeStr == "pixel")
358   {
359     theModel = Graphic3d_TOSM_FRAGMENT;
360   }
361   else if (aTypeStr == "pbr")
362   {
363     theModel = Graphic3d_TOSM_PBR;
364   }
365   else if (aTypeStr == "pbr_facet")
366   {
367     theModel = Graphic3d_TOSM_PBR_FACET;
368   }
369   else if (aTypeStr == "default"
370         || aTypeStr == "def")
371   {
372     theModel = Graphic3d_TOSM_DEFAULT;
373   }
374   else if (aTypeStr.IsIntegerValue())
375   {
376     const int aTypeInt = aTypeStr.IntegerValue();
377     if (aTypeInt <= Graphic3d_TOSM_DEFAULT || aTypeInt >= Graphic3d_TypeOfShadingModel_NB)
378     {
379       return Standard_False;
380     }
381     theModel = (Graphic3d_TypeOfShadingModel)aTypeInt;
382   }
383   else
384   {
385     return Standard_False;
386   }
387   return Standard_True;
388 }
389
390 //=======================================================================
391 //function : parseZLayer
392 //purpose  :
393 //=======================================================================
394 Standard_Boolean ViewerTest::parseZLayer (Standard_CString theArg,
395                                           Standard_Boolean theToAllowInteger,
396                                           Graphic3d_ZLayerId& theLayer)
397 {
398   TCollection_AsciiString aName (theArg);
399   aName.LowerCase();
400   if (aName == "default"
401    || aName == "def")
402   {
403     theLayer = Graphic3d_ZLayerId_Default;
404   }
405   else if (aName == "top")
406   {
407     theLayer = Graphic3d_ZLayerId_Top;
408   }
409   else if (aName == "topmost")
410   {
411     theLayer = Graphic3d_ZLayerId_Topmost;
412   }
413   else if (aName == "overlay"
414         || aName == "toposd")
415   {
416     theLayer = Graphic3d_ZLayerId_TopOSD;
417   }
418   else if (aName == "underlay"
419         || aName == "botosd")
420   {
421     theLayer = Graphic3d_ZLayerId_BotOSD;
422   }
423   else if (aName == "undefined")
424   {
425     theLayer = Graphic3d_ZLayerId_UNKNOWN;
426   }
427   else if (!GetAISContext().IsNull())
428   {
429     const Handle(V3d_Viewer)& aViewer = ViewerTest::GetAISContext()->CurrentViewer();
430     TColStd_SequenceOfInteger aLayers;
431     aViewer->GetAllZLayers (aLayers);
432     for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
433     {
434       Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
435       if (TCollection_AsciiString::IsSameString (aSettings.Name(), aName, Standard_False))
436       {
437         theLayer = aLayeriter.Value();
438         return true;
439       }
440     }
441
442     if (!theToAllowInteger
443      || !aName.IsIntegerValue())
444     {
445       return false;
446     }
447     Graphic3d_ZLayerId aLayer = aName.IntegerValue();
448     if (aLayer == Graphic3d_ZLayerId_UNKNOWN
449      || std::find (aLayers.begin(), aLayers.end(), aLayer) != aLayers.end())
450     {
451       theLayer = aLayer;
452       return true;
453     }
454     return false;
455   }
456   return true;
457 }
458
459 //=======================================================================
460 //function : GetTypeNames
461 //purpose  :
462 //=======================================================================
463 static const char** GetTypeNames()
464 {
465   static const char* names[14] = {"Point","Axis","Trihedron","PlaneTrihedron", "Line","Circle","Plane",
466                           "Shape","ConnectedShape","MultiConn.Shape",
467                           "ConnectedInter.","MultiConn.",
468                           "Constraint","Dimension"};
469   static const char** ThePointer = names;
470   return ThePointer;
471 }
472
473 //=======================================================================
474 //function : GetTypeAndSignfromString
475 //purpose  :
476 //=======================================================================
477 void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,Standard_Integer& TheSign)
478 {
479   const char ** thefullnames = GetTypeNames();
480   Standard_Integer index(-1);
481
482   for(Standard_Integer i=0;i<=13 && index==-1;i++)
483     if(!strcasecmp(name,thefullnames[i]))
484       index = i;
485
486   if(index ==-1){
487     TheType = AIS_KOI_None;
488     TheSign = -1;
489     return;
490   }
491
492   if(index<=6){
493     TheType = AIS_KOI_Datum;
494     TheSign = index+1;
495   }
496   else if (index <=9){
497     TheType = AIS_KOI_Shape;
498     TheSign = index-7;
499   }
500   else if(index<=11){
501     TheType = AIS_KOI_Object;
502     TheSign = index-10;
503   }
504   else{
505     TheType = AIS_KOI_Relation;
506     TheSign = index-12;
507   }
508
509 }
510
511
512
513 #include <string.h>
514 #include <Draw_Interpretor.hxx>
515 #include <Draw.hxx>
516 #include <Draw_Appli.hxx>
517 #include <DBRep.hxx>
518
519
520 #include <TCollection_AsciiString.hxx>
521 #include <V3d_Viewer.hxx>
522 #include <V3d_View.hxx>
523 #include <V3d.hxx>
524
525 #include <AIS_InteractiveContext.hxx>
526 #include <AIS_Shape.hxx>
527 #include <AIS_DisplayMode.hxx>
528 #include <TColStd_MapOfInteger.hxx>
529 #include <AIS_MapOfInteractive.hxx>
530 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
531 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
532 #include <ViewerTest_EventManager.hxx>
533
534 #include <TopoDS_Solid.hxx>
535 #include <BRepTools.hxx>
536 #include <BRep_Builder.hxx>
537 #include <TopAbs_ShapeEnum.hxx>
538
539 #include <TopoDS.hxx>
540 #include <BRep_Tool.hxx>
541
542
543 #include <Draw_Window.hxx>
544 #include <AIS_ListIteratorOfListOfInteractive.hxx>
545 #include <AIS_ListOfInteractive.hxx>
546 #include <AIS_DisplayMode.hxx>
547 #include <TopTools_ListOfShape.hxx>
548 #include <BRepOffsetAPI_MakeThickSolid.hxx>
549
550 //==============================================================================
551 //  VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES
552 //==============================================================================
553 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS(){
554   static ViewerTest_DoubleMapOfInteractiveAndName TheMap;
555   return TheMap;
556 }
557
558 //=======================================================================
559 //function : Display
560 //purpose  :
561 //=======================================================================
562 Standard_Boolean ViewerTest::Display (const TCollection_AsciiString&       theName,
563                                       const Handle(AIS_InteractiveObject)& theObject,
564                                       const Standard_Boolean               theToUpdate,
565                                       const Standard_Boolean               theReplaceIfExists)
566 {
567   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
568   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
569   if (aCtx.IsNull())
570   {
571     Message::SendFail ("Error: AIS context is not available.");
572     return Standard_False;
573   }
574
575   if (aMap.IsBound2 (theName))
576   {
577     if (!theReplaceIfExists)
578     {
579       Message::SendFail() << "Error: other interactive object has been already registered with name: " << theName << ".\n"
580                           << "Please use another name.";
581       return Standard_False;
582     }
583
584     if (Handle(AIS_InteractiveObject) anOldObj = aMap.Find2 (theName))
585     {
586       aCtx->Remove (anOldObj, theObject.IsNull() && theToUpdate);
587     }
588     aMap.UnBind2 (theName);
589   }
590
591   if (theObject.IsNull())
592   {
593     // object with specified name has been already unbound
594     return Standard_True;
595   }
596
597   // unbind AIS object if it was bound with another name
598   aMap.UnBind1 (theObject);
599
600   // can be registered without rebinding
601   aMap.Bind (theObject, theName);
602   aCtx->Display (theObject, theToUpdate);
603   return Standard_True;
604 }
605
606 //! Alias for ViewerTest::Display(), compatibility with old code.
607 Standard_EXPORT Standard_Boolean VDisplayAISObject (const TCollection_AsciiString&       theName,
608                                                     const Handle(AIS_InteractiveObject)& theObject,
609                                                     Standard_Boolean theReplaceIfExists = Standard_True)
610 {
611   return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
612 }
613
614 static NCollection_List<Handle(ViewerTest_EventManager)> theEventMgrs;
615
616 static Handle(V3d_View)&  a3DView()
617 {
618   static Handle(V3d_View) Viou;
619   return Viou;
620 }
621
622
623 Standard_EXPORT Handle(AIS_InteractiveContext)& TheAISContext(){
624   static Handle(AIS_InteractiveContext) aContext;
625   return aContext;
626 }
627
628 const Handle(V3d_View)& ViewerTest::CurrentView()
629 {
630   return a3DView();
631 }
632 void ViewerTest::CurrentView(const Handle(V3d_View)& V)
633 {
634   a3DView() = V;
635 }
636
637 const Handle(AIS_InteractiveContext)& ViewerTest::GetAISContext()
638 {
639   return TheAISContext();
640 }
641
642 void ViewerTest::SetAISContext (const Handle(AIS_InteractiveContext)& aCtx)
643 {
644   TheAISContext() = aCtx;
645   ViewerTest::ResetEventManager();
646 }
647
648 Handle(V3d_Viewer) ViewerTest::GetViewerFromContext()
649 {
650   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
651 }
652
653 Handle(V3d_Viewer) ViewerTest::GetCollectorFromContext()
654 {
655   return !TheAISContext().IsNull() ? TheAISContext()->CurrentViewer() : Handle(V3d_Viewer)();
656 }
657
658
659 void ViewerTest::SetEventManager(const Handle(ViewerTest_EventManager)& EM){
660   theEventMgrs.Prepend(EM);
661 }
662
663 void ViewerTest::UnsetEventManager()
664 {
665   theEventMgrs.RemoveFirst();
666 }
667
668
669 void ViewerTest::ResetEventManager()
670 {
671   theEventMgrs.Clear();
672   theEventMgrs.Prepend (new ViewerTest_EventManager (ViewerTest::CurrentView(), ViewerTest::GetAISContext()));
673 }
674
675 Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
676 {
677   return !theEventMgrs.IsEmpty()
678         ? theEventMgrs.First()
679         : Handle(ViewerTest_EventManager)();
680 }
681
682 //=======================================================================
683 //function : Get Context and active view
684 //purpose  :
685 //=======================================================================
686 static Standard_Boolean getCtxAndView (Handle(AIS_InteractiveContext)& theCtx,
687                                        Handle(V3d_View)&               theView)
688 {
689   theCtx  = ViewerTest::GetAISContext();
690   theView = ViewerTest::CurrentView();
691   if (theCtx.IsNull()
692    || theView.IsNull())
693   {
694     Message::SendFail ("Error: cannot find an active view!");
695     return Standard_False;
696   }
697   return Standard_True;
698 }
699
700 //==============================================================================
701 //function : Clear
702 //purpose  : Remove all the object from the viewer
703 //==============================================================================
704 void ViewerTest::Clear()
705 {
706   if (a3DView().IsNull())
707   {
708     return;
709   }
710
711   NCollection_Sequence<Handle(AIS_InteractiveObject)> aListRemoved;
712   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS()); anObjIter.More(); anObjIter.Next())
713   {
714     const Handle(AIS_InteractiveObject) anObj = anObjIter.Key1();
715     if (anObj->GetContext() != TheAISContext())
716     {
717       continue;
718     }
719
720     Message::SendInfo() << "Remove " << anObjIter.Key2();
721     TheAISContext()->Remove (anObj, Standard_False);
722     aListRemoved.Append (anObj);
723   }
724
725   TheAISContext()->RebuildSelectionStructs();
726   TheAISContext()->UpdateCurrentViewer();
727   if (aListRemoved.Size() == GetMapOfAIS().Extent())
728   {
729     GetMapOfAIS().Clear();
730   }
731   else
732   {
733     for (NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator anObjIter (aListRemoved); anObjIter.More(); anObjIter.Next())
734     {
735       GetMapOfAIS().UnBind1 (anObjIter.Value());
736     }
737   }
738 }
739
740 //==============================================================================
741 //function : CopyIsoAspect
742 //purpose  : Returns copy Prs3d_IsoAspect with new number of isolines.
743 //==============================================================================
744 static Handle(Prs3d_IsoAspect) CopyIsoAspect
745       (const Handle(Prs3d_IsoAspect) &theIsoAspect,
746        const Standard_Integer theNbIsos)
747 {
748   Quantity_Color    aColor = theIsoAspect->Aspect()->Color();
749   Aspect_TypeOfLine aType  = theIsoAspect->Aspect()->Type();
750   Standard_Real     aWidth = theIsoAspect->Aspect()->Width();
751
752   Handle(Prs3d_IsoAspect) aResult =
753     new Prs3d_IsoAspect(aColor, aType, aWidth, theNbIsos);
754
755   return aResult;
756 }
757
758 //==============================================================================
759 //function : visos
760 //purpose  : Returns or sets the number of U- and V- isos and isIsoOnPlane flag
761 //Draw arg : [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]
762 //==============================================================================
763 static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
764 {
765   if (TheAISContext().IsNull()) {
766     di << argv[0] << " Call 'vinit' before!\n";
767     return 1;
768   }
769
770   if (argc <= 1) {
771     di << "Current number of isos : " <<
772       TheAISContext()->IsoNumber(AIS_TOI_IsoU) << " " <<
773       TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n";
774     di << "IsoOnPlane mode is " <<
775       (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n";
776     di << "IsoOnTriangulation mode is " <<
777       (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n";
778     return 0;
779   }
780
781   Standard_Integer aLastInd = argc - 1;
782   Standard_Boolean isChanged = Standard_False;
783   Standard_Integer aNbUIsos = 0;
784   Standard_Integer aNbVIsos = 0;
785
786   if (aLastInd >= 3) {
787     Standard_Boolean isIsoOnPlane = Standard_False;
788
789     if (strcmp(argv[aLastInd], "1") == 0) {
790       isIsoOnPlane = Standard_True;
791       isChanged    = Standard_True;
792     } else if (strcmp(argv[aLastInd], "0") == 0) {
793       isIsoOnPlane = Standard_False;
794       isChanged    = Standard_True;
795     }
796
797     if (isChanged) {
798       aNbVIsos = Draw::Atoi(argv[aLastInd - 1]);
799       aNbUIsos = Draw::Atoi(argv[aLastInd - 2]);
800       aLastInd -= 3;
801
802       di << "New number of isos : " << aNbUIsos << " " << aNbVIsos << "\n";
803       di << "New IsoOnPlane mode is " << (isIsoOnPlane ? "ON" : "OFF") << "\n";
804
805       TheAISContext()->IsoOnPlane(isIsoOnPlane);
806
807       if (aLastInd == 0) {
808         // If there are no shapes provided set the default numbers.
809         TheAISContext()->SetIsoNumber(aNbUIsos, AIS_TOI_IsoU);
810         TheAISContext()->SetIsoNumber(aNbVIsos, AIS_TOI_IsoV);
811       }
812     }
813   }
814
815   Standard_Integer i;
816
817   for (i = 1; i <= aLastInd; i++)
818   {
819     TCollection_AsciiString name(argv[i]);
820     Handle(AIS_InteractiveObject) aShape;
821     GetMapOfAIS().Find2(name, aShape);
822     if (aShape.IsNull())
823     {
824       Message::SendFail() << "Syntax error: object '" << name << "' is not found";
825       return 1;
826     }
827
828     Handle(Prs3d_Drawer) CurDrawer = aShape->Attributes();
829     Handle(Prs3d_IsoAspect) aUIso = CurDrawer->UIsoAspect();
830     Handle(Prs3d_IsoAspect) aVIso = CurDrawer->VIsoAspect();
831     if (isChanged)
832     {
833       CurDrawer->SetUIsoAspect(CopyIsoAspect(aUIso, aNbUIsos));
834       CurDrawer->SetVIsoAspect(CopyIsoAspect(aVIso, aNbVIsos));
835       TheAISContext()->SetLocalAttributes (aShape, CurDrawer, Standard_False);
836       TheAISContext()->Redisplay (aShape, Standard_False);
837     }
838     else
839     {
840       di << "Number of isos for " << argv[i] << " : "
841           << aUIso->Number() << " " << aVIso->Number() << "\n";
842     }
843   }
844
845   if (isChanged) {
846     TheAISContext()->UpdateCurrentViewer();
847   }
848
849   return 0;
850 }
851
852 static Standard_Integer VDispSensi (Draw_Interpretor& ,
853                                     Standard_Integer  theArgNb,
854                                     Standard_CString* )
855 {
856   if (theArgNb > 1)
857   {
858     Message::SendFail ("Error: wrong syntax!");
859     return 1;
860   }
861
862   Handle(AIS_InteractiveContext) aCtx;
863   Handle(V3d_View)               aView;
864   if (!getCtxAndView (aCtx, aView))
865   {
866     return 1;
867   }
868
869   aCtx->DisplayActiveSensitive (aView);
870   return 0;
871
872 }
873
874 static Standard_Integer VClearSensi (Draw_Interpretor& ,
875                                      Standard_Integer  theArgNb,
876                                      Standard_CString* )
877 {
878   if (theArgNb > 1)
879   {
880     Message::SendFail ("Error: wrong syntax!");
881     return 1;
882   }
883
884   Handle(AIS_InteractiveContext) aCtx;
885   Handle(V3d_View)               aView;
886   if (!getCtxAndView (aCtx, aView))
887   {
888     return 1;
889   }
890   aCtx->ClearActiveSensitive (aView);
891   return 0;
892 }
893
894 //==============================================================================
895 //function : VDir
896 //purpose  : To list the displayed object with their attributes
897 //==============================================================================
898 static int VDir (Draw_Interpretor& theDI,
899                  Standard_Integer theNbArgs,
900                  const char** theArgVec)
901 {
902   TCollection_AsciiString aMatch;
903   Standard_Boolean toFormat = Standard_False;
904   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
905   {
906     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
907     anArgCase.LowerCase();
908     if (anArgCase == "-list"
909      || anArgCase == "-format")
910     {
911       toFormat = Standard_True;
912     }
913     else if (aMatch.IsEmpty())
914     {
915       aMatch = theArgVec[anArgIter];
916     }
917     else
918     {
919       Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
920       return 1;
921     }
922   }
923
924   TCollection_AsciiString aRes;
925   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
926   {
927     if (!aMatch.IsEmpty())
928     {
929       const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aMatch + "' '" + anIter.Key2() + "'";
930       if (theDI.Eval (aCheck.ToCString()) == 0
931       && *theDI.Result() != '1')
932       {
933         continue;
934       }
935     }
936
937     if (toFormat)
938     {
939       aRes += TCollection_AsciiString("\t") + anIter.Key2() + "\n";
940     }
941     else
942     {
943       aRes += anIter.Key2() + " ";
944     }
945   }
946   theDI.Reset();
947   theDI << aRes;
948   return 0;
949 }
950
951 //! Auxiliary enumeration
952 enum ViewerTest_StereoPair
953 {
954   ViewerTest_SP_Single,
955   ViewerTest_SP_SideBySide,
956   ViewerTest_SP_OverUnder
957 };
958
959 //==============================================================================
960 //function : VDump
961 //purpose  : To dump the active view snapshot to image file
962 //==============================================================================
963 static Standard_Integer VDump (Draw_Interpretor& theDI,
964                                Standard_Integer  theArgNb,
965                                Standard_CString* theArgVec)
966 {
967   Handle(V3d_View) aView = ViewerTest::CurrentView();
968   if (theArgNb < 2)
969   {
970     Message::SendFail ("Error: wrong number of arguments! Image file name should be specified at least.");
971     return 1;
972   }
973   if (aView.IsNull())
974   {
975     Message::SendFail() << "Error: cannot find an active view!";
976     return 1;
977   }
978
979   Standard_Integer      anArgIter   = 1;
980   Standard_CString      aFilePath   = theArgVec[anArgIter++];
981   ViewerTest_StereoPair aStereoPair = ViewerTest_SP_Single;
982   V3d_ImageDumpOptions  aParams;
983   Handle(Graphic3d_Camera) aCustomCam;
984   aParams.BufferType    = Graphic3d_BT_RGB;
985   aParams.StereoOptions = V3d_SDO_MONO;
986   for (; anArgIter < theArgNb; ++anArgIter)
987   {
988     TCollection_AsciiString anArg (theArgVec[anArgIter]);
989     anArg.LowerCase();
990     if (anArg == "-buffer")
991     {
992       if (++anArgIter >= theArgNb)
993       {
994         Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
995         return 1;
996       }
997
998       TCollection_AsciiString aBufArg (theArgVec[anArgIter]);
999       aBufArg.LowerCase();
1000       if (aBufArg == "rgba")
1001       {
1002         aParams.BufferType = Graphic3d_BT_RGBA;
1003       }
1004       else if (aBufArg == "rgb")
1005       {
1006         aParams.BufferType = Graphic3d_BT_RGB;
1007       }
1008       else if (aBufArg == "red")
1009       {
1010         aParams.BufferType = Graphic3d_BT_Red;
1011       }
1012       else if (aBufArg == "depth")
1013       {
1014         aParams.BufferType = Graphic3d_BT_Depth;
1015       }
1016       else
1017       {
1018         Message::SendFail() << "Error: unknown buffer '" << aBufArg << "'";
1019         return 1;
1020       }
1021     }
1022     else if (anArgIter + 1 < theArgNb
1023           && anArg == "-xrpose")
1024     {
1025       TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
1026       anXRArg.LowerCase();
1027       if (anXRArg == "base")
1028       {
1029         aCustomCam = aView->View()->BaseXRCamera();
1030       }
1031       else if (anXRArg == "head")
1032       {
1033         aCustomCam = aView->View()->PosedXRCamera();
1034       }
1035       else if (anXRArg == "handleft"
1036             || anXRArg == "handright")
1037       {
1038         if (aView->View()->IsActiveXR())
1039         {
1040           aCustomCam = new Graphic3d_Camera();
1041           aView->View()->ComputeXRPosedCameraFromBase (*aCustomCam, anXRArg == "handleft"
1042                                                      ? aView->View()->XRSession()->LeftHandPose()
1043                                                      : aView->View()->XRSession()->RightHandPose());
1044         }
1045       }
1046       else
1047       {
1048         Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
1049         return 1;
1050       }
1051       if (aCustomCam.IsNull())
1052       {
1053         Message::SendFail() << "Error: undefined XR pose";
1054         return 0;
1055       }
1056     }
1057     else if (anArg == "-stereo")
1058     {
1059       if (++anArgIter >= theArgNb)
1060       {
1061         Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
1062         return 1;
1063       }
1064
1065       TCollection_AsciiString aStereoArg (theArgVec[anArgIter]);
1066       aStereoArg.LowerCase();
1067       if (aStereoArg == "l"
1068        || aStereoArg == "left")
1069       {
1070         aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1071       }
1072       else if (aStereoArg == "r"
1073             || aStereoArg == "right")
1074       {
1075         aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1076       }
1077       else if (aStereoArg == "mono")
1078       {
1079         aParams.StereoOptions = V3d_SDO_MONO;
1080       }
1081       else if (aStereoArg == "blended"
1082             || aStereoArg == "blend"
1083             || aStereoArg == "stereo")
1084       {
1085         aParams.StereoOptions = V3d_SDO_BLENDED;
1086       }
1087       else if (aStereoArg == "sbs"
1088             || aStereoArg == "sidebyside")
1089       {
1090         aStereoPair = ViewerTest_SP_SideBySide;
1091       }
1092       else if (aStereoArg == "ou"
1093             || aStereoArg == "overunder")
1094       {
1095         aStereoPair = ViewerTest_SP_OverUnder;
1096       }
1097       else
1098       {
1099         Message::SendFail() << "Error: unknown stereo format '" << aStereoArg << "'";
1100         return 1;
1101       }
1102     }
1103     else if (anArg == "-rgba"
1104           || anArg ==  "rgba")
1105     {
1106       aParams.BufferType = Graphic3d_BT_RGBA;
1107     }
1108     else if (anArg == "-rgb"
1109           || anArg ==  "rgb")
1110     {
1111       aParams.BufferType = Graphic3d_BT_RGB;
1112     }
1113     else if (anArg == "-red"
1114           || anArg ==  "red")
1115     {
1116       aParams.BufferType = Graphic3d_BT_Red;
1117     }
1118     else if (anArg == "-depth"
1119           || anArg ==  "depth")
1120     {
1121       aParams.BufferType = Graphic3d_BT_Depth;
1122     }
1123     else if (anArg == "-width"
1124           || anArg ==  "width"
1125           || anArg ==  "sizex")
1126     {
1127       if (aParams.Width != 0)
1128       {
1129         Message::SendFail() << "Error: wrong syntax at " << theArgVec[anArgIter];
1130         return 1;
1131       }
1132       else if (++anArgIter >= theArgNb)
1133       {
1134         Message::SendFail() << "Error: integer value is expected right after 'width'";
1135         return 1;
1136       }
1137       aParams.Width = Draw::Atoi (theArgVec[anArgIter]);
1138     }
1139     else if (anArg == "-height"
1140           || anArg ==  "height"
1141           || anArg ==  "-sizey")
1142     {
1143       if (aParams.Height != 0)
1144       {
1145         Message::SendFail() << "Error: wrong syntax at " << theArgVec[anArgIter];
1146         return 1;
1147       }
1148       else if (++anArgIter >= theArgNb)
1149       {
1150         Message::SendFail() << "Error: integer value is expected right after 'height'";
1151         return 1;
1152       }
1153       aParams.Height = Draw::Atoi (theArgVec[anArgIter]);
1154     }
1155     else if (anArg == "-tile"
1156           || anArg == "-tilesize")
1157     {
1158       if (++anArgIter >= theArgNb)
1159       {
1160         Message::SendFail() << "Error: integer value is expected right after 'tileSize'";
1161         return 1;
1162       }
1163       aParams.TileSize = Draw::Atoi (theArgVec[anArgIter]);
1164     }
1165     else
1166     {
1167       Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
1168       return 1;
1169     }
1170   }
1171   if ((aParams.Width <= 0 && aParams.Height >  0)
1172    || (aParams.Width >  0 && aParams.Height <= 0))
1173   {
1174     Message::SendFail() << "Error: dimensions " << aParams.Width << "x" << aParams.Height << " are incorrect";
1175     return 1;
1176   }
1177
1178   if (aParams.Width <= 0 || aParams.Height <= 0)
1179   {
1180     aView->Window()->Size (aParams.Width, aParams.Height);
1181   }
1182
1183   Image_AlienPixMap aPixMap;
1184   Image_Format aFormat = Image_Format_UNKNOWN;
1185   switch (aParams.BufferType)
1186   {
1187     case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
1188     case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
1189     case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
1190     case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
1191     case Graphic3d_BT_Red:                 aFormat = Image_Format_Gray;  break;
1192   }
1193
1194   const bool wasImmUpdate = aView->SetImmediateUpdate (false);
1195   Handle(Graphic3d_Camera) aCamBack = aView->Camera();
1196   if (!aCustomCam.IsNull())
1197   {
1198     aView->SetCamera (aCustomCam);
1199   }
1200   switch (aStereoPair)
1201   {
1202     case ViewerTest_SP_Single:
1203     {
1204       if (!aView->ToPixMap (aPixMap, aParams))
1205       {
1206         theDI << "Fail: view dump failed!\n";
1207         return 0;
1208       }
1209       else if (aPixMap.SizeX() != Standard_Size(aParams.Width)
1210             || aPixMap.SizeY() != Standard_Size(aParams.Height))
1211       {
1212         theDI << "Fail: dumped dimensions "    << (Standard_Integer )aPixMap.SizeX() << "x" << (Standard_Integer )aPixMap.SizeY()
1213               << " are lesser than requested " << aParams.Width << "x" << aParams.Height << "\n";
1214       }
1215       break;
1216     }
1217     case ViewerTest_SP_SideBySide:
1218     {
1219       if (!aPixMap.InitZero (aFormat, aParams.Width * 2, aParams.Height))
1220       {
1221         theDI << "Fail: not enough memory for image allocation!\n";
1222         return 0;
1223       }
1224
1225       Image_PixMap aPixMapL, aPixMapR;
1226       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1227                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1228       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizePixelBytes() * aParams.Width,
1229                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1230
1231       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1232       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1233       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1234       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1235       if (!isOk)
1236       {
1237         theDI << "Fail: view dump failed!\n";
1238         return 0;
1239       }
1240       break;
1241     }
1242     case ViewerTest_SP_OverUnder:
1243     {
1244       if (!aPixMap.InitZero (aFormat, aParams.Width, aParams.Height * 2))
1245       {
1246         theDI << "Fail: not enough memory for image allocation!\n";
1247         return 0;
1248       }
1249
1250       Image_PixMap aPixMapL, aPixMapR;
1251       aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
1252                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1253       aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
1254                             aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
1255
1256       aParams.StereoOptions = V3d_SDO_LEFT_EYE;
1257       Standard_Boolean isOk = aView->ToPixMap (aPixMapL, aParams);
1258       aParams.StereoOptions = V3d_SDO_RIGHT_EYE;
1259       isOk          = isOk && aView->ToPixMap (aPixMapR, aParams);
1260       if (!isOk)
1261       {
1262         theDI << "Fail: view dump failed!\n";
1263         return 0;
1264       }
1265       break;
1266     }
1267   }
1268   if (!aCustomCam.IsNull())
1269   {
1270     aView->SetCamera (aCamBack);
1271   }
1272   aView->SetImmediateUpdate (wasImmUpdate);
1273
1274   if (!aPixMap.Save (aFilePath))
1275   {
1276     theDI << "Fail: image can not be saved!\n";
1277   }
1278   return 0;
1279 }
1280
1281 enum TypeOfDispOperation
1282 {
1283   TypeOfDispOperation_SetDispMode,
1284   TypeOfDispOperation_UnsetDispMode
1285 };
1286
1287 //! Displays,Erase...
1288 static void VwrTst_DispErase (const Handle(AIS_InteractiveObject)& thePrs,
1289                                                 const Standard_Integer theMode,
1290                                                 const TypeOfDispOperation theType,
1291                                                 const Standard_Boolean theToUpdate)
1292 {
1293   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1294   switch (theType)
1295   {
1296     case TypeOfDispOperation_SetDispMode:
1297     {
1298       if (!thePrs.IsNull())
1299       {
1300         aCtx->SetDisplayMode (thePrs, theMode, theToUpdate);
1301       }
1302       else
1303       {
1304         aCtx->SetDisplayMode ((AIS_DisplayMode )theMode, theToUpdate);
1305       }
1306       break;
1307     }
1308     case TypeOfDispOperation_UnsetDispMode:
1309     {
1310       if (!thePrs.IsNull())
1311       {
1312         aCtx->UnsetDisplayMode (thePrs, theToUpdate);
1313       }
1314       else
1315       {
1316         aCtx->SetDisplayMode (AIS_WireFrame, theToUpdate);
1317       }
1318       break;
1319     }
1320   }
1321 }
1322
1323 //=======================================================================
1324 //function :
1325 //purpose  :
1326 //=======================================================================
1327 static int VDispMode (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1328 {
1329   if (argc < 1
1330    || argc > 3)
1331   {
1332     Message::SendFail() << "Syntax error: wrong number of arguments";
1333     return 1;
1334   }
1335
1336   TypeOfDispOperation aType = TCollection_AsciiString (argv[0]) == "vunsetdispmode"
1337                             ? TypeOfDispOperation_UnsetDispMode
1338                             : TypeOfDispOperation_SetDispMode;
1339   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1340   if (aType == TypeOfDispOperation_UnsetDispMode)
1341   {
1342     if (argc == 1)
1343     {
1344       if (aCtx->NbSelected() == 0)
1345       {
1346         VwrTst_DispErase (Handle(AIS_InteractiveObject)(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1347       }
1348       else
1349       {
1350         for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1351         {
1352           VwrTst_DispErase (aCtx->SelectedInteractive(), -1, TypeOfDispOperation_UnsetDispMode, Standard_False);
1353         }
1354       }
1355       aCtx->UpdateCurrentViewer();
1356     }
1357     else
1358     {
1359       TCollection_AsciiString aName = argv[1];
1360       Handle(AIS_InteractiveObject) aPrs;
1361       if (GetMapOfAIS().Find2 (aName, aPrs)
1362       && !aPrs.IsNull())
1363       {
1364         VwrTst_DispErase (aPrs, -1, TypeOfDispOperation_UnsetDispMode, Standard_True);
1365       }
1366     }
1367   }
1368   else if (argc == 2)
1369   {
1370     Standard_Integer aDispMode = Draw::Atoi (argv[1]);
1371     if (aCtx->NbSelected() == 0
1372      && aType == TypeOfDispOperation_SetDispMode)
1373     {
1374       VwrTst_DispErase (Handle(AIS_InteractiveObject)(), aDispMode, TypeOfDispOperation_SetDispMode, Standard_True);
1375     }
1376     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
1377     {
1378       VwrTst_DispErase (aCtx->SelectedInteractive(), aDispMode, aType, Standard_False);
1379     }
1380     aCtx->UpdateCurrentViewer();
1381   }
1382   else
1383   {
1384     Handle(AIS_InteractiveObject) aPrs;
1385     TCollection_AsciiString aName (argv[1]);
1386     if (GetMapOfAIS().Find2 (aName, aPrs)
1387      && !aPrs.IsNull())
1388     {
1389       VwrTst_DispErase (aPrs, Draw::Atoi(argv[2]), aType, Standard_True);
1390     }
1391   }
1392   return 0;
1393 }
1394
1395
1396 //=======================================================================
1397 //function :
1398 //purpose  :
1399 //=======================================================================
1400 static int VSubInt(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1401 {
1402   if(argc==1) return 1;
1403   Standard_Integer On = Draw::Atoi(argv[1]);
1404   const Handle(AIS_InteractiveContext)& Ctx = ViewerTest::GetAISContext();
1405
1406   if(argc==2)
1407   {
1408     TCollection_AsciiString isOnOff = On == 1 ? "on" : "off";
1409     di << "Sub intensite is turned " << isOnOff << " for " << Ctx->NbSelected() << "objects\n";
1410     for (Ctx->InitSelected(); Ctx->MoreSelected(); Ctx->NextSelected())
1411     {
1412       if(On==1)
1413       {
1414         Ctx->SubIntensityOn (Ctx->SelectedInteractive(), Standard_False);
1415       }
1416       else
1417       {
1418         Ctx->SubIntensityOff (Ctx->SelectedInteractive(), Standard_False);
1419       }
1420     }
1421
1422     Ctx->UpdateCurrentViewer();
1423   }
1424   else {
1425     Handle(AIS_InteractiveObject) IO;
1426     TCollection_AsciiString name = argv[2];
1427     if (GetMapOfAIS().Find2 (name, IO)
1428     && !IO.IsNull())
1429     {
1430       if(On==1)
1431         Ctx->SubIntensityOn(IO, Standard_True);
1432       else
1433         Ctx->SubIntensityOff(IO, Standard_True);
1434     }
1435     else return 1;
1436   }
1437   return 0;
1438 }
1439
1440 //! Auxiliary class to iterate presentations from different collections.
1441 class ViewTest_PrsIter
1442 {
1443 public:
1444
1445   //! Create and initialize iterator object.
1446   ViewTest_PrsIter (const TCollection_AsciiString& theName)
1447   : mySource (IterSource_All)
1448   {
1449     NCollection_Sequence<TCollection_AsciiString> aNames;
1450     if (!theName.IsEmpty())
1451     aNames.Append (theName);
1452     Init (aNames);
1453   }
1454
1455   //! Create and initialize iterator object.
1456   ViewTest_PrsIter (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1457   : mySource (IterSource_All)
1458   {
1459     Init (theNames);
1460   }
1461
1462   //! Initialize the iterator.
1463   void Init (const NCollection_Sequence<TCollection_AsciiString>& theNames)
1464   {
1465     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1466     mySeq = theNames;
1467     mySelIter.Nullify();
1468     myCurrent.Nullify();
1469     myCurrentTrs.Nullify();
1470     if (!mySeq.IsEmpty())
1471     {
1472       mySource = IterSource_List;
1473       mySeqIter = NCollection_Sequence<TCollection_AsciiString>::Iterator (mySeq);
1474     }
1475     else if (aCtx->NbSelected() > 0)
1476     {
1477       mySource  = IterSource_Selected;
1478       mySelIter = aCtx;
1479       mySelIter->InitSelected();
1480     }
1481     else
1482     {
1483       mySource = IterSource_All;
1484       myMapIter.Initialize (GetMapOfAIS());
1485     }
1486     initCurrent();
1487   }
1488
1489   const TCollection_AsciiString& CurrentName() const
1490   {
1491     return myCurrentName;
1492   }
1493
1494   const Handle(AIS_InteractiveObject)& Current() const
1495   {
1496     return myCurrent;
1497   }
1498
1499   const Handle(Standard_Transient)& CurrentTrs() const
1500   {
1501     return myCurrentTrs;
1502   }
1503
1504   //! @return true if iterator points to valid object within collection
1505   Standard_Boolean More() const
1506   {
1507     switch (mySource)
1508     {
1509       case IterSource_All:      return myMapIter.More();
1510       case IterSource_List:     return mySeqIter.More();
1511       case IterSource_Selected: return mySelIter->MoreSelected();
1512     }
1513     return Standard_False;
1514   }
1515
1516   //! Go to the next item.
1517   void Next()
1518   {
1519     myCurrentName.Clear();
1520     myCurrentTrs.Nullify();
1521     myCurrent.Nullify();
1522     switch (mySource)
1523     {
1524       case IterSource_All:
1525       {
1526         myMapIter.Next();
1527         break;
1528       }
1529       case IterSource_List:
1530       {
1531         mySeqIter.Next();
1532         break;
1533       }
1534       case IterSource_Selected:
1535       {
1536         mySelIter->NextSelected();
1537         break;
1538       }
1539     }
1540     initCurrent();
1541   }
1542
1543 private:
1544
1545   void initCurrent()
1546   {
1547     switch (mySource)
1548     {
1549       case IterSource_All:
1550       {
1551         if (myMapIter.More())
1552         {
1553           myCurrentName = myMapIter.Key2();
1554           myCurrentTrs  = myMapIter.Key1();
1555           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1556         }
1557         break;
1558       }
1559       case IterSource_List:
1560       {
1561         if (mySeqIter.More())
1562         {
1563           if (!GetMapOfAIS().IsBound2 (mySeqIter.Value()))
1564           {
1565             Message::SendFail() << "Error: object " << mySeqIter.Value() << " is not displayed!";
1566             return;
1567           }
1568           myCurrentName = mySeqIter.Value();
1569           myCurrentTrs  = GetMapOfAIS().Find2 (mySeqIter.Value());
1570           myCurrent     = Handle(AIS_InteractiveObject)::DownCast (myCurrentTrs);
1571         }
1572         break;
1573       }
1574       case IterSource_Selected:
1575       {
1576         if (mySelIter->MoreSelected())
1577         {
1578           myCurrentName = GetMapOfAIS().Find1 (mySelIter->SelectedInteractive());
1579           myCurrent     = mySelIter->SelectedInteractive();
1580         }
1581         break;
1582       }
1583     }
1584   }
1585
1586 private:
1587
1588   enum IterSource
1589   {
1590     IterSource_All,
1591     IterSource_List,
1592     IterSource_Selected
1593   };
1594
1595 private:
1596
1597   Handle(AIS_InteractiveContext) mySelIter;    //!< iterator for current (selected) objects (IterSource_Selected)
1598   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName myMapIter; //!< iterator for map of all objects (IterSource_All)
1599   NCollection_Sequence<TCollection_AsciiString>           mySeq;
1600   NCollection_Sequence<TCollection_AsciiString>::Iterator mySeqIter;
1601
1602   TCollection_AsciiString        myCurrentName;//!< current item name
1603   Handle(Standard_Transient)     myCurrentTrs; //!< current item (as transient object)
1604   Handle(AIS_InteractiveObject)  myCurrent;    //!< current item
1605
1606   IterSource                     mySource;     //!< iterated collection
1607
1608 };
1609
1610 //! Parse interior style name.
1611 static bool parseInteriorStyle (const TCollection_AsciiString& theArg,
1612                                 Aspect_InteriorStyle& theStyle)
1613 {
1614   TCollection_AsciiString anArg (theArg);
1615   anArg.LowerCase();
1616   if (anArg == "empty")
1617   {
1618     theStyle = Aspect_IS_EMPTY;
1619   }
1620   else if (anArg == "hollow")
1621   {
1622     theStyle = Aspect_IS_HOLLOW;
1623   }
1624   else if (anArg == "solid")
1625   {
1626     theStyle = Aspect_IS_SOLID;
1627   }
1628   else if (anArg == "hatch")
1629   {
1630     theStyle = Aspect_IS_HATCH;
1631   }
1632   else if (anArg == "hiddenline"
1633         || anArg == "hidden-line"
1634         || anArg == "hidden_line")
1635   {
1636     theStyle = Aspect_IS_HIDDENLINE;
1637   }
1638   else if (anArg == "point")
1639   {
1640     theStyle = Aspect_IS_POINT;
1641   }
1642   else if (theArg.IsIntegerValue())
1643   {
1644     const Standard_Integer anIntStyle = theArg.IntegerValue();
1645     if (anIntStyle < Aspect_IS_EMPTY || anIntStyle > Aspect_IS_POINT)
1646     {
1647       return false;
1648     }
1649     theStyle = (Aspect_InteriorStyle)anIntStyle;
1650   }
1651   else
1652   {
1653     return false;
1654   }
1655   return true;
1656 }
1657
1658 //! Auxiliary structure for VAspects
1659 struct ViewerTest_AspectsChangeSet
1660 {
1661   Standard_Integer             ToSetVisibility;
1662   Standard_Integer             Visibility;
1663
1664   Standard_Integer             ToSetColor;
1665   Quantity_Color               Color;
1666   Standard_Integer             ToSetBackFaceColor;
1667   Quantity_Color               BackFaceColor;
1668
1669   Standard_Integer             ToSetLineWidth;
1670   Standard_Real                LineWidth;
1671
1672   Standard_Integer             ToSetTypeOfLine;
1673   uint16_t                     StippleLinePattern;
1674   uint16_t                     StippleLineFactor;
1675
1676   Standard_Integer             ToSetTypeOfMarker;
1677   Aspect_TypeOfMarker          TypeOfMarker;
1678   Handle(Image_PixMap)         MarkerImage;
1679
1680   Standard_Integer             ToSetMarkerSize;
1681   Standard_Real                MarkerSize;
1682
1683   Standard_Integer             ToSetTransparency;
1684   Standard_Real                Transparency;
1685
1686   Standard_Integer             ToSetAlphaMode;
1687   Graphic3d_AlphaMode          AlphaMode;
1688   Standard_ShortReal           AlphaCutoff;
1689
1690   Standard_Integer             ToSetMaterial;
1691   Graphic3d_NameOfMaterial     Material;
1692   TCollection_AsciiString      MatName;
1693
1694   NCollection_Sequence<TopoDS_Shape> SubShapes;
1695
1696   Standard_Integer             ToSetShowFreeBoundary;
1697   Standard_Integer             ToSetFreeBoundaryWidth;
1698   Standard_Real                FreeBoundaryWidth;
1699   Standard_Integer             ToSetFreeBoundaryColor;
1700   Quantity_Color               FreeBoundaryColor;
1701
1702   Standard_Integer             ToEnableIsoOnTriangulation;
1703
1704   Standard_Integer             ToSetFaceBoundaryDraw;
1705   Standard_Integer             ToSetFaceBoundaryUpperContinuity;
1706   GeomAbs_Shape                FaceBoundaryUpperContinuity;
1707
1708   Standard_Integer             ToSetFaceBoundaryColor;
1709   Quantity_Color               FaceBoundaryColor;
1710
1711   Standard_Integer             ToSetFaceBoundaryWidth;
1712   Standard_Real                FaceBoundaryWidth;
1713
1714   Standard_Integer             ToSetTypeOfFaceBoundaryLine;
1715   Aspect_TypeOfLine            TypeOfFaceBoundaryLine;
1716
1717   Standard_Integer             ToSetMaxParamValue;
1718   Standard_Real                MaxParamValue;
1719
1720   Standard_Integer             ToSetSensitivity;
1721   Standard_Integer             SelectionMode;
1722   Standard_Integer             Sensitivity;
1723
1724   Standard_Integer             ToSetHatch;
1725   Standard_Integer             StdHatchStyle;
1726   TCollection_AsciiString      PathToHatchPattern;
1727
1728   Standard_Integer             ToSetShadingModel;
1729   Graphic3d_TypeOfShadingModel ShadingModel;
1730   TCollection_AsciiString      ShadingModelName;
1731
1732   Standard_Integer             ToSetInterior;
1733   Aspect_InteriorStyle         InteriorStyle;
1734
1735   Standard_Integer             ToSetDrawSilhouette;
1736
1737   Standard_Integer             ToSetDrawEdges;
1738   Standard_Integer             ToSetQuadEdges;
1739
1740   Standard_Integer             ToSetEdgeColor;
1741   Quantity_ColorRGBA           EdgeColor;
1742
1743   Standard_Integer             ToSetEdgeWidth;
1744   Standard_Real                EdgeWidth;
1745
1746   Standard_Integer             ToSetTypeOfEdge;
1747   Aspect_TypeOfLine            TypeOfEdge;
1748
1749   //! Empty constructor
1750   ViewerTest_AspectsChangeSet()
1751   : ToSetVisibility   (0),
1752     Visibility        (1),
1753     ToSetColor        (0),
1754     Color             (DEFAULT_COLOR),
1755     ToSetBackFaceColor(0),
1756     BackFaceColor     (DEFAULT_COLOR),
1757     ToSetLineWidth    (0),
1758     LineWidth         (1.0),
1759     ToSetTypeOfLine   (0),
1760     StippleLinePattern(0xFFFF),
1761     StippleLineFactor (1),
1762     ToSetTypeOfMarker (0),
1763     TypeOfMarker      (Aspect_TOM_PLUS),
1764     ToSetMarkerSize   (0),
1765     MarkerSize        (1.0),
1766     ToSetTransparency (0),
1767     Transparency      (0.0),
1768     ToSetAlphaMode    (0),
1769     AlphaMode         (Graphic3d_AlphaMode_BlendAuto),
1770     AlphaCutoff       (0.5f),
1771     ToSetMaterial     (0),
1772     Material          (Graphic3d_NOM_DEFAULT),
1773     ToSetShowFreeBoundary      (0),
1774     ToSetFreeBoundaryWidth     (0),
1775     FreeBoundaryWidth          (1.0),
1776     ToSetFreeBoundaryColor     (0),
1777     FreeBoundaryColor          (DEFAULT_FREEBOUNDARY_COLOR),
1778     ToEnableIsoOnTriangulation (0),
1779     //
1780     ToSetFaceBoundaryDraw      (0),
1781     ToSetFaceBoundaryUpperContinuity (0),
1782     FaceBoundaryUpperContinuity(GeomAbs_CN),
1783     ToSetFaceBoundaryColor     (0),
1784     FaceBoundaryColor          (Quantity_NOC_BLACK),
1785     ToSetFaceBoundaryWidth     (0),
1786     FaceBoundaryWidth          (1.0f),
1787     ToSetTypeOfFaceBoundaryLine(0),
1788     TypeOfFaceBoundaryLine     (Aspect_TOL_SOLID),
1789     //
1790     ToSetMaxParamValue         (0),
1791     MaxParamValue              (500000),
1792     ToSetSensitivity           (0),
1793     SelectionMode              (-1),
1794     Sensitivity                (-1),
1795     ToSetHatch                 (0),
1796     StdHatchStyle              (-1),
1797     ToSetShadingModel          (0),
1798     ShadingModel               (Graphic3d_TOSM_DEFAULT),
1799     ToSetInterior              (0),
1800     InteriorStyle              (Aspect_IS_SOLID),
1801     ToSetDrawSilhouette (0),
1802     ToSetDrawEdges    (0),
1803     ToSetQuadEdges    (0),
1804     ToSetEdgeColor    (0),
1805     ToSetEdgeWidth    (0),
1806     EdgeWidth         (1.0),
1807     ToSetTypeOfEdge   (0),
1808     TypeOfEdge        (Aspect_TOL_SOLID)
1809     {}
1810
1811   //! @return true if no changes have been requested
1812   Standard_Boolean IsEmpty() const
1813   {
1814     return ToSetVisibility        == 0
1815         && ToSetLineWidth         == 0
1816         && ToSetTransparency      == 0
1817         && ToSetAlphaMode         == 0
1818         && ToSetColor             == 0
1819         && ToSetBackFaceColor     == 0
1820         && ToSetMaterial          == 0
1821         && ToSetShowFreeBoundary  == 0
1822         && ToSetFreeBoundaryColor == 0
1823         && ToSetFreeBoundaryWidth == 0
1824         && ToEnableIsoOnTriangulation == 0
1825         && ToSetFaceBoundaryDraw == 0
1826         && ToSetFaceBoundaryUpperContinuity == 0
1827         && ToSetFaceBoundaryColor == 0
1828         && ToSetFaceBoundaryWidth == 0
1829         && ToSetTypeOfFaceBoundaryLine == 0
1830         && ToSetMaxParamValue     == 0
1831         && ToSetSensitivity       == 0
1832         && ToSetHatch             == 0
1833         && ToSetShadingModel      == 0
1834         && ToSetInterior          == 0
1835         && ToSetDrawSilhouette    == 0
1836         && ToSetDrawEdges         == 0
1837         && ToSetQuadEdges         == 0
1838         && ToSetEdgeColor         == 0
1839         && ToSetEdgeWidth         == 0
1840         && ToSetTypeOfEdge        == 0;
1841   }
1842
1843   //! @return true if properties are valid
1844   Standard_Boolean Validate() const
1845   {
1846     Standard_Boolean isOk = Standard_True;
1847     if (Visibility != 0 && Visibility != 1)
1848     {
1849       Message::SendFail() << "Error: the visibility should be equal to 0 or 1 (0 - invisible; 1 - visible) (specified " << Visibility << ")";
1850       isOk = Standard_False;
1851     }
1852     if (LineWidth <= 0.0
1853      || LineWidth >  10.0)
1854     {
1855       Message::SendFail() << "Error: the width should be within [1; 10] range (specified " << LineWidth << ")";
1856       isOk = Standard_False;
1857     }
1858     if (Transparency < 0.0
1859      || Transparency > 1.0)
1860     {
1861       Message::SendFail() << "Error: the transparency should be within [0; 1] range (specified " << Transparency << ")";
1862       isOk = Standard_False;
1863     }
1864     if (ToSetAlphaMode == 1
1865      && (AlphaCutoff <= 0.0f || AlphaCutoff >= 1.0f))
1866     {
1867       Message::SendFail() << "Error: alpha cutoff value should be within (0; 1) range (specified " << AlphaCutoff << ")";
1868       isOk = Standard_False;
1869     }
1870     if (FreeBoundaryWidth <= 0.0
1871      || FreeBoundaryWidth >  10.0)
1872     {
1873       Message::SendFail() << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")";
1874       isOk = Standard_False;
1875     }
1876     if (MaxParamValue < 0.0)
1877     {
1878       Message::SendFail() << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")";
1879       isOk = Standard_False;
1880     }
1881     if (Sensitivity <= 0 && ToSetSensitivity)
1882     {
1883       Message::SendFail() << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")";
1884       isOk = Standard_False;
1885     }
1886     if (ToSetHatch == 1 && StdHatchStyle < 0 && PathToHatchPattern == "")
1887     {
1888       Message::SendFail ("Error: hatch style must be specified");
1889       isOk = Standard_False;
1890     }
1891     if (ToSetShadingModel == 1
1892     && (ShadingModel < Graphic3d_TOSM_DEFAULT || ShadingModel > Graphic3d_TOSM_PBR_FACET))
1893     {
1894       Message::SendFail() << "Error: unknown shading model " << ShadingModelName << ".";
1895       isOk = Standard_False;
1896     }
1897     return isOk;
1898   }
1899
1900   //! Apply aspects to specified drawer.
1901   bool Apply (const Handle(Prs3d_Drawer)& theDrawer)
1902   {
1903     bool toRecompute = false;
1904     const Handle(Prs3d_Drawer)& aDefDrawer = ViewerTest::GetAISContext()->DefaultDrawer();
1905     if (ToSetShowFreeBoundary != 0)
1906     {
1907       theDrawer->SetFreeBoundaryDraw (ToSetShowFreeBoundary == 1);
1908       toRecompute = true;
1909     }
1910     if (ToSetFreeBoundaryWidth != 0)
1911     {
1912       if (ToSetFreeBoundaryWidth != -1
1913        || theDrawer->HasOwnFreeBoundaryAspect())
1914       {
1915         if (!theDrawer->HasOwnFreeBoundaryAspect())
1916         {
1917           Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
1918           *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
1919           theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
1920           toRecompute = true;
1921         }
1922         theDrawer->FreeBoundaryAspect()->SetWidth (FreeBoundaryWidth);
1923       }
1924     }
1925     if (ToSetFreeBoundaryColor != 0)
1926     {
1927       Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0);
1928       *aBoundaryAspect->Aspect() = *theDrawer->FreeBoundaryAspect()->Aspect();
1929       aBoundaryAspect->SetColor (FreeBoundaryColor);
1930       theDrawer->SetFreeBoundaryAspect (aBoundaryAspect);
1931       toRecompute = true;
1932     }
1933     if (ToSetTypeOfLine != 0)
1934     {
1935       if (ToSetTypeOfLine != -1
1936        || theDrawer->HasOwnLineAspect()
1937        || theDrawer->HasOwnWireAspect()
1938        || theDrawer->HasOwnFreeBoundaryAspect()
1939        || theDrawer->HasOwnUnFreeBoundaryAspect()
1940        || theDrawer->HasOwnSeenLineAspect())
1941       {
1942         toRecompute = theDrawer->SetOwnLineAspects() || toRecompute;
1943         theDrawer->LineAspect()->Aspect()->SetLinePattern (StippleLinePattern);
1944         theDrawer->LineAspect()->Aspect()->SetLineStippleFactor (StippleLineFactor);
1945         theDrawer->WireAspect()->Aspect()->SetLinePattern (StippleLinePattern);
1946         theDrawer->WireAspect()->Aspect()->SetLineStippleFactor (StippleLineFactor);
1947         theDrawer->FreeBoundaryAspect()->Aspect()->SetLinePattern (StippleLinePattern);
1948         theDrawer->FreeBoundaryAspect()->Aspect()->SetLineStippleFactor (StippleLineFactor);
1949         theDrawer->UnFreeBoundaryAspect()->Aspect()->SetLinePattern (StippleLinePattern);
1950         theDrawer->UnFreeBoundaryAspect()->Aspect()->SetLineStippleFactor (StippleLineFactor);
1951         theDrawer->SeenLineAspect()->Aspect()->SetLinePattern (StippleLinePattern);
1952         theDrawer->SeenLineAspect()->Aspect()->SetLineStippleFactor (StippleLineFactor);
1953       }
1954     }
1955     if (ToSetTypeOfMarker != 0)
1956     {
1957       if (ToSetTypeOfMarker != -1
1958        || theDrawer->HasOwnPointAspect())
1959       {
1960         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
1961         theDrawer->PointAspect()->SetTypeOfMarker (TypeOfMarker);
1962         theDrawer->PointAspect()->Aspect()->SetMarkerImage (MarkerImage.IsNull() ? Handle(Graphic3d_MarkerImage)() : new Graphic3d_MarkerImage (MarkerImage));
1963       }
1964     }
1965     if (ToSetMarkerSize != 0)
1966     {
1967       if (ToSetMarkerSize != -1
1968        || theDrawer->HasOwnPointAspect())
1969       {
1970         toRecompute = theDrawer->SetupOwnPointAspect (aDefDrawer) || toRecompute;
1971         theDrawer->PointAspect()->SetScale (MarkerSize);
1972         toRecompute = true;
1973       }
1974     }
1975     if (ToSetMaxParamValue != 0)
1976     {
1977       if (ToSetMaxParamValue != -1
1978        || theDrawer->HasOwnMaximalParameterValue())
1979       {
1980         theDrawer->SetMaximalParameterValue (MaxParamValue);
1981         toRecompute = true;
1982       }
1983     }
1984     if (ToSetFaceBoundaryDraw != 0)
1985     {
1986       if (ToSetFaceBoundaryDraw != -1
1987        || theDrawer->HasOwnFaceBoundaryDraw())
1988       {
1989         toRecompute = true;
1990         theDrawer->SetFaceBoundaryDraw (ToSetFaceBoundaryDraw == 1);
1991       }
1992     }
1993     if (ToSetFaceBoundaryUpperContinuity != 0)
1994     {
1995       if (ToSetFaceBoundaryUpperContinuity != -1
1996        || theDrawer->HasOwnFaceBoundaryUpperContinuity())
1997       {
1998         toRecompute = true;
1999         if (ToSetFaceBoundaryUpperContinuity == -1)
2000         {
2001           theDrawer->UnsetFaceBoundaryUpperContinuity();
2002         }
2003         else
2004         {
2005           theDrawer->SetFaceBoundaryUpperContinuity (FaceBoundaryUpperContinuity);
2006         }
2007       }
2008     }
2009     if (ToSetFaceBoundaryColor != 0)
2010     {
2011       if (ToSetFaceBoundaryColor != -1
2012        || theDrawer->HasOwnFaceBoundaryAspect())
2013       {
2014         if (ToSetFaceBoundaryColor == -1)
2015         {
2016           toRecompute = true;
2017           theDrawer->SetFaceBoundaryAspect (Handle(Prs3d_LineAspect)());
2018         }
2019         else
2020         {
2021           toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2022           theDrawer->FaceBoundaryAspect()->SetColor (FaceBoundaryColor);
2023         }
2024       }
2025     }
2026     if (ToSetFaceBoundaryWidth != 0)
2027     {
2028       if (ToSetFaceBoundaryWidth != -1
2029        || theDrawer->HasOwnFaceBoundaryAspect())
2030       {
2031         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2032         theDrawer->FaceBoundaryAspect()->SetWidth (FaceBoundaryWidth);
2033       }
2034     }
2035     if (ToSetTypeOfFaceBoundaryLine != 0)
2036     {
2037       if (ToSetTypeOfFaceBoundaryLine != -1
2038        || theDrawer->HasOwnFaceBoundaryAspect())
2039       {
2040         toRecompute = theDrawer->SetupOwnFaceBoundaryAspect (aDefDrawer) || toRecompute;
2041         theDrawer->FaceBoundaryAspect()->SetTypeOfLine (TypeOfFaceBoundaryLine);
2042       }
2043     }
2044     if (ToSetShadingModel != 0)
2045     {
2046       if (ToSetShadingModel != -1
2047        || theDrawer->HasOwnShadingAspect())
2048       {
2049         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2050         theDrawer->ShadingAspect()->Aspect()->SetShadingModel (ShadingModel);
2051       }
2052     }
2053     if (ToSetBackFaceColor != 0)
2054     {
2055       if (ToSetBackFaceColor != -1
2056        || theDrawer->HasOwnShadingAspect())
2057       {
2058         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2059         theDrawer->ShadingAspect()->SetColor (BackFaceColor, Aspect_TOFM_BACK_SIDE);
2060       }
2061     }
2062     if (ToSetAlphaMode != 0)
2063     {
2064       if (ToSetAlphaMode != -1
2065        || theDrawer->HasOwnShadingAspect())
2066       {
2067         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2068         theDrawer->ShadingAspect()->Aspect()->SetAlphaMode (AlphaMode, AlphaCutoff);
2069       }
2070     }
2071     if (ToSetHatch != 0)
2072     {
2073       if (ToSetHatch != -1
2074       ||  theDrawer->HasOwnShadingAspect())
2075       {
2076         theDrawer->SetupOwnShadingAspect (aDefDrawer);
2077         Handle(Graphic3d_AspectFillArea3d) anAsp = theDrawer->ShadingAspect()->Aspect();
2078         if (ToSetHatch == -1)
2079         {
2080           anAsp->SetInteriorStyle (Aspect_IS_SOLID);
2081         }
2082         else
2083         {
2084           anAsp->SetInteriorStyle (Aspect_IS_HATCH);
2085           if (!PathToHatchPattern.IsEmpty())
2086           {
2087             Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
2088             if (anImage->Load (TCollection_AsciiString (PathToHatchPattern.ToCString())))
2089             {
2090               anAsp->SetHatchStyle (new Graphic3d_HatchStyle (anImage));
2091             }
2092             else
2093             {
2094               Message::SendFail() << "Error: cannot load the following image: " << PathToHatchPattern;
2095             }
2096           }
2097           else if (StdHatchStyle != -1)
2098           {
2099             anAsp->SetHatchStyle (new Graphic3d_HatchStyle ((Aspect_HatchStyle)StdHatchStyle));
2100           }
2101         }
2102         toRecompute = true;
2103       }
2104     }
2105     if (ToSetInterior != 0)
2106     {
2107       if (ToSetInterior != -1
2108        || theDrawer->HasOwnShadingAspect())
2109       {
2110         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2111         theDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (InteriorStyle);
2112         if (InteriorStyle == Aspect_IS_HATCH
2113          && theDrawer->ShadingAspect()->Aspect()->HatchStyle().IsNull())
2114         {
2115           theDrawer->ShadingAspect()->Aspect()->SetHatchStyle (Aspect_HS_VERTICAL);
2116         }
2117       }
2118     }
2119     if (ToSetDrawSilhouette != 0)
2120     {
2121       if (ToSetDrawSilhouette != -1
2122        || theDrawer->HasOwnShadingAspect())
2123       {
2124         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2125         theDrawer->ShadingAspect()->Aspect()->SetDrawSilhouette (ToSetDrawSilhouette == 1);
2126       }
2127     }
2128     if (ToSetDrawEdges != 0)
2129     {
2130       if (ToSetDrawEdges != -1
2131        || theDrawer->HasOwnShadingAspect())
2132       {
2133         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2134         theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetDrawEdges == 1);
2135       }
2136     }
2137     if (ToSetQuadEdges != 0)
2138     {
2139       if (ToSetQuadEdges != -1
2140           || theDrawer->HasOwnShadingAspect())
2141       {
2142         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2143         theDrawer->ShadingAspect()->Aspect()->SetSkipFirstEdge (ToSetQuadEdges == 1);
2144       }
2145     }
2146     if (ToSetEdgeWidth != 0)
2147     {
2148       if (ToSetEdgeWidth != -1
2149        || theDrawer->HasOwnShadingAspect())
2150       {
2151         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2152         theDrawer->ShadingAspect()->Aspect()->SetEdgeWidth (EdgeWidth);
2153       }
2154     }
2155     if (ToSetTypeOfEdge != 0)
2156     {
2157       if (ToSetTypeOfEdge != -1
2158        || theDrawer->HasOwnShadingAspect())
2159       {
2160         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2161         theDrawer->ShadingAspect()->Aspect()->SetEdgeLineType (TypeOfEdge);
2162         if (ToSetInterior == 0)
2163         {
2164           theDrawer->ShadingAspect()->Aspect()->SetDrawEdges (ToSetTypeOfEdge == 1
2165                                                            && TypeOfEdge != Aspect_TOL_EMPTY);
2166         }
2167       }
2168     }
2169     if (ToSetEdgeColor != 0)
2170     {
2171       if (ToSetEdgeColor != -1
2172        || theDrawer->HasOwnShadingAspect())
2173       {
2174         toRecompute = theDrawer->SetupOwnShadingAspect (aDefDrawer) || toRecompute;
2175         if (ToSetEdgeColor == -1)
2176         {
2177           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (theDrawer->ShadingAspect()->Aspect()->InteriorColor());
2178         }
2179         else
2180         {
2181           theDrawer->ShadingAspect()->Aspect()->SetEdgeColor (EdgeColor);
2182         }
2183       }
2184     }
2185     return toRecompute;
2186   }
2187 };
2188
2189 //==============================================================================
2190 //function : VAspects
2191 //purpose  :
2192 //==============================================================================
2193 static Standard_Integer VAspects (Draw_Interpretor& theDI,
2194                                   Standard_Integer  theArgNb,
2195                                   const char**      theArgVec)
2196 {
2197   TCollection_AsciiString aCmdName (theArgVec[0]);
2198   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
2199   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
2200   if (aCtx.IsNull())
2201   {
2202     Message::SendFail ("Error: no active view!");
2203     return 1;
2204   }
2205
2206   Standard_Integer anArgIter = 1;
2207   Standard_Boolean isDefaults = Standard_False;
2208   NCollection_Sequence<TCollection_AsciiString> aNames;
2209   for (; anArgIter < theArgNb; ++anArgIter)
2210   {
2211     TCollection_AsciiString anArg = theArgVec[anArgIter];
2212     if (anUpdateTool.parseRedrawMode (anArg))
2213     {
2214       continue;
2215     }
2216     else if (!anArg.IsEmpty()
2217            && anArg.Value (1) != '-')
2218     {
2219       aNames.Append (anArg);
2220     }
2221     else
2222     {
2223       if (anArg == "-defaults")
2224       {
2225         isDefaults = Standard_True;
2226         ++anArgIter;
2227       }
2228       break;
2229     }
2230   }
2231
2232   if (!aNames.IsEmpty() && isDefaults)
2233   {
2234     Message::SendFail ("Error: wrong syntax. If -defaults is used there should not be any objects' names!");
2235     return 1;
2236   }
2237
2238   NCollection_Sequence<ViewerTest_AspectsChangeSet> aChanges;
2239   aChanges.Append (ViewerTest_AspectsChangeSet());
2240   ViewerTest_AspectsChangeSet* aChangeSet = &aChanges.ChangeLast();
2241
2242   // parse syntax of legacy commands
2243   bool toParseAliasArgs = false;
2244   Standard_Boolean toDump = 0;
2245   Standard_Boolean toCompactDump = 0;
2246   Standard_Integer aDumpDepth = -1;
2247   if (aCmdName == "vsetwidth")
2248   {
2249     if (aNames.IsEmpty()
2250     || !aNames.Last().IsRealValue())
2251     {
2252       Message::SendFail ("Error: not enough arguments!");
2253       return 1;
2254     }
2255     aChangeSet->ToSetLineWidth = 1;
2256     aChangeSet->LineWidth = aNames.Last().RealValue();
2257     aNames.Remove (aNames.Length());
2258   }
2259   else if (aCmdName == "vunsetwidth")
2260   {
2261     aChangeSet->ToSetLineWidth = -1;
2262   }
2263   else if (aCmdName == "vsetcolor")
2264   {
2265     if (aNames.IsEmpty())
2266     {
2267       Message::SendFail ("Error: not enough arguments!");
2268       return 1;
2269     }
2270     aChangeSet->ToSetColor = 1;
2271
2272     Quantity_NameOfColor aColor = Quantity_NOC_BLACK;
2273     Standard_Boolean     isOk   = Standard_False;
2274     if (Quantity_Color::ColorFromName (aNames.Last().ToCString(), aColor))
2275     {
2276       aChangeSet->Color = aColor;
2277       aNames.Remove (aNames.Length());
2278       isOk = Standard_True;
2279     }
2280     else if (Quantity_Color::ColorFromHex (aNames.Last().ToCString(), aChangeSet->Color))
2281     {
2282       aNames.Remove (aNames.Length());
2283       isOk = Standard_True;
2284     }
2285     else if (aNames.Length() >= 3)
2286     {
2287       const char* anArgVec[3] =
2288       {
2289         aNames.Value (aNames.Upper() - 2).ToCString(),
2290         aNames.Value (aNames.Upper() - 1).ToCString(),
2291         aNames.Value (aNames.Upper() - 0).ToCString(),
2292       };
2293
2294       Standard_Integer aNbParsed = Draw::ParseColor (3, anArgVec, aChangeSet->Color);
2295       isOk = aNbParsed == 3;
2296       aNames.Remove (aNames.Length());
2297       aNames.Remove (aNames.Length());
2298       aNames.Remove (aNames.Length());
2299     }
2300     if (!isOk)
2301     {
2302       Message::SendFail ("Error: not enough arguments!");
2303       return 1;
2304     }
2305   }
2306   else if (aCmdName == "vunsetcolor")
2307   {
2308     aChangeSet->ToSetColor = -1;
2309   }
2310   else if (aCmdName == "vsettransparency")
2311   {
2312     if (aNames.IsEmpty()
2313     || !aNames.Last().IsRealValue())
2314     {
2315       Message::SendFail ("Error: not enough arguments!");
2316       return 1;
2317     }
2318     aChangeSet->ToSetTransparency = 1;
2319     aChangeSet->Transparency  = aNames.Last().RealValue();
2320     aNames.Remove (aNames.Length());
2321   }
2322   else if (aCmdName == "vunsettransparency")
2323   {
2324     aChangeSet->ToSetTransparency = -1;
2325   }
2326   else if (aCmdName == "vsetmaterial")
2327   {
2328     if (aNames.IsEmpty())
2329     {
2330       Message::SendFail ("Error: not enough arguments!");
2331       return 1;
2332     }
2333     aChangeSet->ToSetMaterial = 1;
2334     aChangeSet->MatName = aNames.Last();
2335     aNames.Remove (aNames.Length());
2336     if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2337     {
2338       Message::SendFail() << "Syntax error: unknown material '" << aChangeSet->MatName << "'.";
2339       return 1;
2340     }
2341   }
2342   else if (aCmdName == "vunsetmaterial")
2343   {
2344     aChangeSet->ToSetMaterial = -1;
2345   }
2346   else if (aCmdName == "vsetinteriorstyle")
2347   {
2348     if (aNames.IsEmpty()
2349     || !aNames.Last().IsRealValue())
2350     {
2351       Message::SendFail ("Error: not enough arguments!");
2352       return 1;
2353     }
2354     aChangeSet->ToSetInterior = 1;
2355     if (!parseInteriorStyle (aNames.Last(), aChangeSet->InteriorStyle))
2356     {
2357       Message::SendFail() << "Error: wrong syntax at " << aNames.Last();
2358       return 1;
2359     }
2360     aNames.Remove (aNames.Length());
2361   }
2362   else if (aCmdName == "vsetedgetype")
2363   {
2364     aChangeSet->ToSetDrawEdges = 1;
2365     toParseAliasArgs = true;
2366   }
2367   else if (aCmdName == "vunsetedgetype")
2368   {
2369     aChangeSet->ToSetDrawEdges  = -1;
2370     aChangeSet->ToSetEdgeColor  = -1;
2371     aChangeSet->ToSetTypeOfEdge = -1;
2372     aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
2373   }
2374   else if (aCmdName == "vshowfaceboundary")
2375   {
2376     aChangeSet->ToSetFaceBoundaryDraw = 1;
2377     toParseAliasArgs = true;
2378     if (aNames.Size() >= 2
2379      && aNames.Value (2).IsIntegerValue())
2380     {
2381       if (aNames.Size() == 7)
2382       {
2383         if (ViewerTest::ParseLineType (aNames.Value (7).ToCString(), aChangeSet->TypeOfFaceBoundaryLine))
2384         {
2385           aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2386           aNames.Remove (7);
2387         }
2388       }
2389       if (aNames.Size() == 6
2390        && aNames.Value (6).IsRealValue())
2391       {
2392         aChangeSet->ToSetFaceBoundaryWidth = 1;
2393         aChangeSet->FaceBoundaryWidth = aNames.Value (6).RealValue();
2394         aNames.Remove (6);
2395       }
2396       if (aNames.Size() == 5
2397        && aNames.Value (3).IsIntegerValue()
2398        && aNames.Value (4).IsIntegerValue()
2399        && aNames.Value (5).IsIntegerValue())
2400       {
2401         aChangeSet->ToSetFaceBoundaryColor = 1;
2402         aChangeSet->FaceBoundaryColor = Quantity_Color (aNames.Value (3).IntegerValue() / 255.0,
2403                                                         aNames.Value (4).IntegerValue() / 255.0,
2404                                                         aNames.Value (5).IntegerValue() / 255.0,
2405                                                         Quantity_TOC_sRGB);
2406         aNames.Remove (5);
2407         aNames.Remove (4);
2408         aNames.Remove (3);
2409       }
2410       if (aNames.Size() == 2)
2411       {
2412         toParseAliasArgs = false;
2413         aChangeSet->ToSetFaceBoundaryDraw = aNames.Value (2).IntegerValue() == 1 ? 1 : -1;
2414         aNames.Remove (2);
2415       }
2416     }
2417   }
2418   else if (anArgIter >= theArgNb)
2419   {
2420     Message::SendFail ("Error: not enough arguments!");
2421     return 1;
2422   }
2423
2424   if (!aChangeSet->IsEmpty()
2425    && !toParseAliasArgs)
2426   {
2427     anArgIter = theArgNb;
2428   }
2429   for (; anArgIter < theArgNb; ++anArgIter)
2430   {
2431     TCollection_AsciiString anArg = theArgVec[anArgIter];
2432     anArg.LowerCase();
2433     if (anArg == "-setwidth"
2434      || anArg == "-width"
2435      || anArg == "-setlinewidth"
2436      || anArg == "-linewidth"
2437      || anArg == "-setedgewidth"
2438      || anArg == "-setedgeswidth"
2439      || anArg == "-edgewidth"
2440      || anArg == "-edgeswidth"
2441      || anArg == "-setfaceboundarywidth"
2442      || anArg == "-setboundarywidth"
2443      || anArg == "-faceboundarywidth"
2444      || anArg == "-boundarywidth")
2445     {
2446       if (++anArgIter >= theArgNb)
2447       {
2448         Message::SendFail() << "Error: wrong syntax at " << anArg;
2449         return 1;
2450       }
2451
2452       const Standard_Real aWidth = Draw::Atof (theArgVec[anArgIter]);
2453       if (anArg == "-setedgewidth"
2454        || anArg == "-setedgeswidth"
2455        || anArg == "-edgewidth"
2456        || anArg == "-edgeswidth"
2457        || aCmdName == "vsetedgetype")
2458       {
2459         aChangeSet->ToSetEdgeWidth = 1;
2460         aChangeSet->EdgeWidth = aWidth;
2461       }
2462       else if (anArg == "-setfaceboundarywidth"
2463             || anArg == "-setboundarywidth"
2464             || anArg == "-faceboundarywidth"
2465             || anArg == "-boundarywidth"
2466             || aCmdName == "vshowfaceboundary")
2467       {
2468         aChangeSet->ToSetFaceBoundaryWidth = 1;
2469         aChangeSet->FaceBoundaryWidth = aWidth;
2470       }
2471       else
2472       {
2473         aChangeSet->ToSetLineWidth = 1;
2474         aChangeSet->LineWidth = aWidth;
2475       }
2476     }
2477     else if (anArg == "-unsetwidth"
2478           || anArg == "-unsetlinewidth"
2479           || anArg == "-unsetedgewidth")
2480     {
2481       if (anArg == "-unsetedgewidth")
2482       {
2483         aChangeSet->ToSetEdgeWidth = -1;
2484         aChangeSet->EdgeWidth = 1.0;
2485       }
2486       else
2487       {
2488         aChangeSet->ToSetLineWidth = -1;
2489         aChangeSet->LineWidth = 1.0;
2490       }
2491     }
2492     else if (anArg == "-settransp"
2493           || anArg == "-settransparency"
2494           || anArg == "-transparency"
2495           || anArg == "-transp")
2496     {
2497       if (++anArgIter >= theArgNb)
2498       {
2499         Message::SendFail() << "Error: wrong syntax at " << anArg;
2500         return 1;
2501       }
2502       aChangeSet->ToSetTransparency = 1;
2503       aChangeSet->Transparency = Draw::Atof (theArgVec[anArgIter]);
2504       if (aChangeSet->Transparency >= 0.0
2505        && aChangeSet->Transparency <= Precision::Confusion())
2506       {
2507         aChangeSet->ToSetTransparency = -1;
2508         aChangeSet->Transparency = 0.0;
2509       }
2510     }
2511     else if (anArg == "-setalphamode"
2512           || anArg == "-alphamode")
2513     {
2514       if (++anArgIter >= theArgNb)
2515       {
2516         Message::SendFail() << "Error: wrong syntax at " << anArg;
2517         return 1;
2518       }
2519       aChangeSet->ToSetAlphaMode = 1;
2520       aChangeSet->AlphaCutoff = 0.5f;
2521       {
2522         TCollection_AsciiString aParam (theArgVec[anArgIter]);
2523         aParam.LowerCase();
2524         if (aParam == "opaque")
2525         {
2526           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Opaque;
2527         }
2528         else if (aParam == "mask")
2529         {
2530           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Mask;
2531         }
2532         else if (aParam == "blend")
2533         {
2534           aChangeSet->AlphaMode = Graphic3d_AlphaMode_Blend;
2535         }
2536         else if (aParam == "blendauto"
2537               || aParam == "auto")
2538         {
2539           aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
2540         }
2541         else
2542         {
2543           Message::SendFail() << "Error: wrong syntax at " << aParam;
2544           return 1;
2545         }
2546       }
2547
2548       if (anArgIter + 1 < theArgNb
2549        && theArgVec[anArgIter + 1][0] != '-')
2550       {
2551         TCollection_AsciiString aParam2 (theArgVec[anArgIter + 1]);
2552         if (aParam2.IsRealValue())
2553         {
2554           aChangeSet->AlphaCutoff = (float )aParam2.RealValue();
2555           ++anArgIter;
2556         }
2557       }
2558     }
2559     else if (anArg == "-setvis"
2560           || anArg == "-setvisibility"
2561           || anArg == "-visibility")
2562     {
2563       if (++anArgIter >= theArgNb)
2564       {
2565         Message::SendFail() << "Error: wrong syntax at " << anArg;
2566         return 1;
2567       }
2568
2569       aChangeSet->ToSetVisibility = 1;
2570       aChangeSet->Visibility = Draw::Atoi (theArgVec[anArgIter]);
2571     }
2572     else if (anArg == "-setalpha"
2573           || anArg == "-alpha")
2574     {
2575       if (++anArgIter >= theArgNb)
2576       {
2577         Message::SendFail() << "Error: wrong syntax at " << anArg;
2578         return 1;
2579       }
2580       aChangeSet->ToSetTransparency = 1;
2581       aChangeSet->Transparency  = Draw::Atof (theArgVec[anArgIter]);
2582       if (aChangeSet->Transparency < 0.0
2583        || aChangeSet->Transparency > 1.0)
2584       {
2585         Message::SendFail() << "Error: the transparency should be within [0; 1] range (specified " << aChangeSet->Transparency << ")";
2586         return 1;
2587       }
2588       aChangeSet->Transparency = 1.0 - aChangeSet->Transparency;
2589       if (aChangeSet->Transparency >= 0.0
2590        && aChangeSet->Transparency <= Precision::Confusion())
2591       {
2592         aChangeSet->ToSetTransparency = -1;
2593         aChangeSet->Transparency = 0.0;
2594       }
2595     }
2596     else if (anArg == "-unsettransp"
2597           || anArg == "-unsettransparency"
2598           || anArg == "-unsetalpha"
2599           || anArg == "-opaque")
2600     {
2601       aChangeSet->ToSetTransparency = -1;
2602       aChangeSet->Transparency = 0.0;
2603     }
2604     else if (anArg == "-setcolor"
2605           || anArg == "-color"
2606           || anArg == "-setbackfacecolor"
2607           || anArg == "-backfacecolor"
2608           || anArg == "-setbackcolor"
2609           || anArg == "-backcolor"
2610           || anArg == "-setfaceboundarycolor"
2611           || anArg == "-setboundarycolor"
2612           || anArg == "-faceboundarycolor"
2613           || anArg == "-boundarycolor")
2614     {
2615       Quantity_Color aColor;
2616       Standard_Integer aNbParsed = Draw::ParseColor (theArgNb  - anArgIter - 1,
2617                                                      theArgVec + anArgIter + 1,
2618                                                      aColor);
2619       if (aNbParsed == 0)
2620       {
2621         Message::SendFail() << "Syntax error at '" << anArg << "'";
2622         return 1;
2623       }
2624       anArgIter += aNbParsed;
2625       if (aCmdName == "vsetedgetype")
2626       {
2627         aChangeSet->ToSetEdgeColor = 1;
2628         aChangeSet->EdgeColor = Quantity_ColorRGBA (aColor);
2629       }
2630       else if (aCmdName == "vshowfaceboundary"
2631             || anArg == "-setfaceboundarycolor"
2632             || anArg == "-setboundarycolor"
2633             || anArg == "-faceboundarycolor"
2634             || anArg == "-boundarycolor")
2635       {
2636         aChangeSet->ToSetFaceBoundaryColor = 1;
2637         aChangeSet->FaceBoundaryColor = aColor;
2638       }
2639       else if (anArg == "-setbackfacecolor"
2640             || anArg == "-backfacecolor"
2641             || anArg == "-setbackcolor"
2642             || anArg == "-backcolor")
2643       {
2644         aChangeSet->ToSetBackFaceColor = 1;
2645         aChangeSet->BackFaceColor = aColor;
2646       }
2647       else
2648       {
2649         aChangeSet->ToSetColor = 1;
2650         aChangeSet->Color = aColor;
2651       }
2652     }
2653     else if (anArg == "-setlinetype"
2654           || anArg == "-linetype"
2655           || anArg == "-setedgetype"
2656           || anArg == "-setedgestype"
2657           || anArg == "-edgetype"
2658           || anArg == "-edgestype"
2659           || anArg == "-setfaceboundarystyle"
2660           || anArg == "-faceboundarystyle"
2661           || anArg == "-boundarystyle"
2662           || anArg == "-setfaceboundarytype"
2663           || anArg == "-faceboundarytype"
2664           || anArg == "-setboundarytype"
2665           || anArg == "-boundarytype"
2666           || anArg == "-type")
2667     {
2668       if (++anArgIter >= theArgNb)
2669       {
2670         Message::SendFail() << "Error: wrong syntax at " << anArg;
2671         return 1;
2672       }
2673       Aspect_TypeOfLine aLineType = Aspect_TOL_EMPTY;
2674       uint16_t aLinePattern = 0xFFFF;
2675       if (!ViewerTest::ParseLineType (theArgVec[anArgIter], aLineType, aLinePattern))
2676       {
2677         Message::SendFail() << "Error: wrong syntax at " << anArg;
2678         return 1;
2679       }
2680
2681       if (anArg == "-setedgetype"
2682        || anArg == "-setedgestype"
2683        || anArg == "-edgetype"
2684        || anArg == "-edgestype"
2685        || aCmdName == "vsetedgetype")
2686       {
2687         aChangeSet->TypeOfEdge = Graphic3d_Aspects::DefaultLineTypeForPattern (aLinePattern);
2688         aChangeSet->ToSetTypeOfEdge = 1;
2689       }
2690       else if (anArg == "-setfaceboundarystyle"
2691             || anArg == "-faceboundarystyle"
2692             || anArg == "-boundarystyle"
2693             || anArg == "-setfaceboundarytype"
2694             || anArg == "-faceboundarytype"
2695             || anArg == "-setboundarytype"
2696             || anArg == "-boundarytype"
2697             || aCmdName == "vshowfaceboundary")
2698       {
2699         aChangeSet->TypeOfFaceBoundaryLine = Graphic3d_Aspects::DefaultLineTypeForPattern (aLinePattern);
2700         aChangeSet->ToSetTypeOfFaceBoundaryLine = 1;
2701       }
2702       else
2703       {
2704         aChangeSet->StippleLinePattern = aLinePattern;
2705         aChangeSet->ToSetTypeOfLine = 1;
2706       }
2707     }
2708     else if (anArg == "-unsetlinetype"
2709           || anArg == "-unsetedgetype"
2710           || anArg == "-unsetedgestype")
2711     {
2712       if (anArg == "-unsetedgetype"
2713        || anArg == "-unsetedgestype")
2714       {
2715         aChangeSet->ToSetTypeOfEdge = -1;
2716       }
2717       else
2718       {
2719         aChangeSet->ToSetTypeOfLine = -1;
2720       }
2721     }
2722     else if (anArg == "-setstipplelinefactor"
2723           || anArg == "-setstipplefactor"
2724           || anArg == "-setlinefactor"
2725           || anArg == "-stipplelinefactor"
2726           || anArg == "-stipplefactor"
2727           || anArg == "-linefactor")
2728     {
2729       if (aChangeSet->ToSetTypeOfLine == -1)
2730       {
2731         Message::SendFail() << "Error: -setStippleLineFactor requires -setLineType";
2732         return 1;
2733       }
2734       if (++anArgIter >= theArgNb)
2735       {
2736         Message::SendFail() << "Error: wrong syntax at " << anArg;
2737         return 1;
2738       }
2739       aChangeSet->StippleLineFactor = (uint16_t )Draw::Atoi (theArgVec[anArgIter]);
2740     }
2741     else if (anArg == "-setmarkertype"
2742           || anArg == "-markertype"
2743           || anArg == "-setpointtype"
2744           || anArg == "-pointtype")
2745     {
2746       if (++anArgIter >= theArgNb)
2747       {
2748         Message::SendFail() << "Error: wrong syntax at " << anArg;
2749         return 1;
2750       }
2751       if (!ViewerTest::ParseMarkerType (theArgVec[anArgIter], aChangeSet->TypeOfMarker, aChangeSet->MarkerImage))
2752       {
2753         Message::SendFail() << "Error: wrong syntax at " << anArg;
2754         return 1;
2755       }
2756
2757       aChangeSet->ToSetTypeOfMarker = 1;
2758     }
2759     else if (anArg == "-unsetmarkertype"
2760           || anArg == "-unsetpointtype")
2761     {
2762       aChangeSet->ToSetTypeOfMarker = -1;
2763     }
2764     else if (anArg == "-setmarkersize"
2765           || anArg == "-markersize"
2766           || anArg == "-setpointsize"
2767           || anArg == "-pointsize")
2768     {
2769       if (++anArgIter >= theArgNb)
2770       {
2771         Message::SendFail() << "Error: wrong syntax at " << anArg;
2772         return 1;
2773       }
2774       aChangeSet->ToSetMarkerSize = 1;
2775       aChangeSet->MarkerSize = Draw::Atof (theArgVec[anArgIter]);
2776     }
2777     else if (anArg == "-unsetmarkersize"
2778           || anArg == "-unsetpointsize")
2779     {
2780       aChangeSet->ToSetMarkerSize = -1;
2781       aChangeSet->MarkerSize = 1.0;
2782     }
2783     else if (anArg == "-unsetcolor")
2784     {
2785       aChangeSet->ToSetColor = -1;
2786       aChangeSet->Color = DEFAULT_COLOR;
2787     }
2788     else if (anArg == "-setmat"
2789           || anArg == "-mat"
2790           || anArg == "-setmaterial"
2791           || anArg == "-material")
2792     {
2793       if (++anArgIter >= theArgNb)
2794       {
2795         Message::SendFail() << "Error: wrong syntax at " << anArg;
2796         return 1;
2797       }
2798       aChangeSet->ToSetMaterial = 1;
2799       aChangeSet->MatName = theArgVec[anArgIter];
2800       if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeSet->MatName.ToCString(), aChangeSet->Material))
2801       {
2802         Message::SendFail() << "Syntax error: unknown material '" << aChangeSet->MatName << "'.";
2803         return 1;
2804       }
2805     }
2806     else if (anArg == "-unsetmat"
2807           || anArg == "-unsetmaterial")
2808     {
2809       aChangeSet->ToSetMaterial = -1;
2810       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
2811     }
2812     else if (anArg == "-subshape"
2813           || anArg == "-subshapes")
2814     {
2815       if (isDefaults)
2816       {
2817         Message::SendFail() << "Error: wrong syntax. -subshapes can not be used together with -defaults call!";
2818         return 1;
2819       }
2820
2821       if (aNames.IsEmpty())
2822       {
2823         Message::SendFail() << "Error: main objects should specified explicitly when -subshapes is used!";
2824         return 1;
2825       }
2826
2827       aChanges.Append (ViewerTest_AspectsChangeSet());
2828       aChangeSet = &aChanges.ChangeLast();
2829
2830       for (++anArgIter; anArgIter < theArgNb; ++anArgIter)
2831       {
2832         Standard_CString aSubShapeName = theArgVec[anArgIter];
2833         if (*aSubShapeName == '-')
2834         {
2835           --anArgIter;
2836           break;
2837         }
2838
2839         TopoDS_Shape aSubShape = DBRep::Get (aSubShapeName);
2840         if (aSubShape.IsNull())
2841         {
2842           Message::SendFail() << "Error: shape " << aSubShapeName << " doesn't found!";
2843           return 1;
2844         }
2845         aChangeSet->SubShapes.Append (aSubShape);
2846       }
2847
2848       if (aChangeSet->SubShapes.IsEmpty())
2849       {
2850         Message::SendFail() << "Error: empty list is specified after -subshapes!";
2851         return 1;
2852       }
2853     }
2854     else if (anArg == "-setfreeboundary"
2855           || anArg == "-freeboundary"
2856           || anArg == "-setfb"
2857           || anArg == "-fb")
2858     {
2859       bool toEnable = true;
2860       if (!Draw::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2861       {
2862         Message::SendFail() << "Error: wrong syntax at " << anArg;
2863         return 1;
2864       }
2865       ++anArgIter;
2866       aChangeSet->ToSetShowFreeBoundary = toEnable ? 1 : -1;
2867     }
2868     else if (anArg == "-setfreeboundarywidth"
2869           || anArg == "-freeboundarywidth"
2870           || anArg == "-setfbwidth"
2871           || anArg == "-fbwidth")
2872     {
2873       if (++anArgIter >= theArgNb)
2874       {
2875         Message::SendFail() << "Error: wrong syntax at " << anArg;
2876         return 1;
2877       }
2878       aChangeSet->ToSetFreeBoundaryWidth = 1;
2879       aChangeSet->FreeBoundaryWidth = Draw::Atof (theArgVec[anArgIter]);
2880     }
2881     else if (anArg == "-unsetfreeboundarywidth"
2882           || anArg == "-unsetfbwidth")
2883     {
2884       aChangeSet->ToSetFreeBoundaryWidth = -1;
2885       aChangeSet->FreeBoundaryWidth = 1.0;
2886     }
2887     else if (anArg == "-setfreeboundarycolor"
2888           || anArg == "-freeboundarycolor"
2889           || anArg == "-setfbcolor"
2890           || anArg == "-fbcolor")
2891     {
2892       Standard_Integer aNbParsed = Draw::ParseColor (theArgNb  - anArgIter - 1,
2893                                                      theArgVec + anArgIter + 1,
2894                                                      aChangeSet->FreeBoundaryColor);
2895       if (aNbParsed == 0)
2896       {
2897         Message::SendFail() << "Syntax error at '" << anArg << "'";
2898         return 1;
2899       }
2900       anArgIter += aNbParsed;
2901       aChangeSet->ToSetFreeBoundaryColor = 1;
2902     }
2903     else if (anArg == "-unsetfreeboundarycolor"
2904           || anArg == "-unsetfbcolor")
2905     {
2906       aChangeSet->ToSetFreeBoundaryColor = -1;
2907       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
2908     }
2909     else if (anArg == "-setisoontriangulation"
2910           || anArg == "-isoontriangulation"
2911           || anArg == "-setisoontriang"
2912           || anArg == "-isoontriang")
2913     {
2914       bool toEnable = true;
2915       if (!Draw::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2916       {
2917         Message::SendFail() << "Error: wrong syntax at " << anArg;
2918         return 1;
2919       }
2920       ++anArgIter;
2921       aChangeSet->ToEnableIsoOnTriangulation = toEnable ? 1 : -1;
2922     }
2923     else if (anArg == "-setfaceboundarydraw"
2924           || anArg == "-setdrawfaceboundary"
2925           || anArg == "-setdrawfaceboundaries"
2926           || anArg == "-setshowfaceboundary"
2927           || anArg == "-setshowfaceboundaries"
2928           || anArg == "-setdrawfaceedges"
2929           || anArg == "-faceboundarydraw"
2930           || anArg == "-drawfaceboundary"
2931           || anArg == "-drawfaceboundaries"
2932           || anArg == "-showfaceboundary"
2933           || anArg == "-showfaceboundaries"
2934           || anArg == "-drawfaceedges"
2935           || anArg == "-faceboundary"
2936           || anArg == "-faceboundaries"
2937           || anArg == "-faceedges")
2938     {
2939       bool toEnable = true;
2940       if (!Draw::ParseOnOff (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "", toEnable))
2941       {
2942         Message::SendFail() << "Error: wrong syntax at " << anArg;
2943         return 1;
2944       }
2945       ++anArgIter;
2946       aChangeSet->ToSetFaceBoundaryDraw = toEnable ? 1 : -1;
2947     }
2948     else if (anArg == "-unsetfaceboundary"
2949           || anArg == "-unsetboundary")
2950     {
2951       aChangeSet->ToSetFaceBoundaryDraw  = -1;
2952       aChangeSet->ToSetFaceBoundaryColor = -1;
2953     }
2954     else if (anArg == "-setmostcontinuity"
2955           || anArg == "-mostcontinuity")
2956     {
2957       TCollection_AsciiString aClassArg (anArgIter + 1 < theArgNb ? theArgVec[anArgIter + 1] : "");
2958       aClassArg.LowerCase();
2959       GeomAbs_Shape aClass = GeomAbs_CN;
2960       if (aClassArg == "c0"
2961        || aClassArg == "0")
2962       {
2963         aClass = GeomAbs_C0;
2964       }
2965       else if (aClassArg == "c1"
2966             || aClassArg == "1")
2967       {
2968         aClass = GeomAbs_C1;
2969       }
2970       else if (aClassArg == "c2"
2971             || aClassArg == "2")
2972       {
2973         aClass = GeomAbs_C2;
2974       }
2975       else if (aClassArg == "c3"
2976             || aClassArg == "3")
2977       {
2978         aClass = GeomAbs_C3;
2979       }
2980       else if (aClassArg == "cn"
2981             || aClassArg == "n")
2982       {
2983         aClass = GeomAbs_CN;
2984       }
2985       else
2986       {
2987         Message::SendFail() << "Syntax error at '" << anArg << "'";
2988         return 1;
2989       }
2990
2991       ++anArgIter;
2992       aChangeSet->ToSetFaceBoundaryUpperContinuity = 1;
2993       aChangeSet->FaceBoundaryUpperContinuity = aClass;
2994     }
2995     else if (anArg == "-setmaxparamvalue"
2996           || anArg == "-maxparamvalue")
2997     {
2998       if (++anArgIter >= theArgNb)
2999       {
3000         Message::SendFail() << "Error: wrong syntax at " << anArg;
3001         return 1;
3002       }
3003       aChangeSet->ToSetMaxParamValue = 1;
3004       aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]);
3005     }
3006     else if (anArg == "-setsensitivity"
3007           || anArg == "-sensitivity")
3008     {
3009       if (isDefaults)
3010       {
3011         Message::SendFail() << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!";
3012         return 1;
3013       }
3014
3015       if (aNames.IsEmpty())
3016       {
3017         Message::SendFail() << "Error: object and selection mode should specified explicitly when -setSensitivity is used!";
3018         return 1;
3019       }
3020
3021       if (anArgIter + 2 >= theArgNb)
3022       {
3023         Message::SendFail() << "Error: wrong syntax at " << anArg;
3024         return 1;
3025       }
3026       aChangeSet->ToSetSensitivity = 1;
3027       aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
3028       aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
3029     }
3030     else if (anArg == "-sethatch"
3031           || anArg == "-hatch")
3032     {
3033       if (isDefaults)
3034       {
3035         Message::SendFail() << "Error: wrong syntax. -setHatch can not be used together with -defaults call!";
3036         return 1;
3037       }
3038
3039       if (aNames.IsEmpty())
3040       {
3041         Message::SendFail() << "Error: object should be specified explicitly when -setHatch is used!";
3042         return 1;
3043       }
3044
3045       aChangeSet->ToSetHatch = 1;
3046       TCollection_AsciiString anArgHatch (theArgVec[++anArgIter]);
3047       if (anArgHatch.Length() <= 2)
3048       {
3049         const Standard_Integer anIntStyle = Draw::Atoi (anArgHatch.ToCString());
3050         if (anIntStyle < 0
3051          || anIntStyle >= Aspect_HS_NB)
3052         {
3053           Message::SendFail() << "Error: hatch style is out of range [0, " << (Aspect_HS_NB - 1) << "]!";
3054           return 1;
3055         }
3056         aChangeSet->StdHatchStyle = anIntStyle;
3057       }
3058       else
3059       {
3060         aChangeSet->PathToHatchPattern = anArgHatch;
3061       }
3062     }
3063     else if (anArg == "-setshadingmodel"
3064           || anArg == "-setshading"
3065           || anArg == "-shadingmodel"
3066           || anArg == "-shading")
3067     {
3068       if (++anArgIter >= theArgNb)
3069       {
3070         Message::SendFail() << "Error: wrong syntax at " << anArg;
3071         return 1;
3072       }
3073       aChangeSet->ToSetShadingModel = 1;
3074       aChangeSet->ShadingModelName  = theArgVec[anArgIter];
3075       if (!ViewerTest::ParseShadingModel (theArgVec[anArgIter], aChangeSet->ShadingModel))
3076       {
3077         Message::SendFail() << "Error: wrong syntax at " << anArg;
3078         return 1;
3079       }
3080     }
3081     else if (anArg == "-unsetshadingmodel")
3082     {
3083       aChangeSet->ToSetShadingModel = -1;
3084       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3085     }
3086     else if (anArg == "-setinterior"
3087           || anArg == "-setinteriorstyle"
3088           || anArg == "-interior"
3089           || anArg == "-interiorstyle")
3090     {
3091       if (++anArgIter >= theArgNb)
3092       {
3093         Message::SendFail() << "Error: wrong syntax at " << anArg;
3094         return 1;
3095       }
3096       aChangeSet->ToSetInterior = 1;
3097       if (!parseInteriorStyle (theArgVec[anArgIter], aChangeSet->InteriorStyle))
3098       {
3099         Message::SendFail() << "Error: wrong syntax at " << anArg;
3100         return 1;
3101       }
3102     }
3103     else if (anArg == "-unsetinterior")
3104     {
3105       aChangeSet->ToSetInterior = -1;
3106       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3107     }
3108     else if (anArg == "-setdrawoutline"
3109           || anArg == "-setdrawsilhouette"
3110           || anArg == "-setoutline"
3111           || anArg == "-setsilhouette"
3112           || anArg == "-outline"
3113           || anArg == "-outlined"
3114           || anArg == "-silhouette")
3115     {
3116       bool toDrawOutline = true;
3117       if (anArgIter + 1 < theArgNb
3118        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toDrawOutline))
3119       {
3120         ++anArgIter;
3121       }
3122       aChangeSet->ToSetDrawSilhouette = toDrawOutline ? 1 : -1;
3123     }
3124     else if (anArg == "-setdrawedges"
3125           || anArg == "-setdrawedge"
3126           || anArg == "-drawedges"
3127           || anArg == "-drawedge"
3128           || anArg == "-edges")
3129     {
3130       bool toDrawEdges = true;
3131       if (anArgIter + 1 < theArgNb
3132        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toDrawEdges))
3133       {
3134         ++anArgIter;
3135       }
3136       aChangeSet->ToSetDrawEdges = toDrawEdges ? 1 : -1;
3137     }
3138     else if (anArg == "-setquadedges"
3139           || anArg == "-setquads"
3140           || anArg == "-quads"
3141           || anArg == "-skipfirstedge")
3142     {
3143       bool isQuadMode = true;
3144       if (anArgIter + 1 < theArgNb
3145        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isQuadMode))
3146       {
3147         ++anArgIter;
3148       }
3149       aChangeSet->ToSetQuadEdges = isQuadMode ? 1 : -1;
3150     }
3151     else if (anArg == "-setedgecolor"
3152           || anArg == "-setedgescolor"
3153           || anArg == "-edgecolor"
3154           || anArg == "-edgescolor")
3155     {
3156       Standard_Integer aNbParsed = Draw::ParseColor (theArgNb  - anArgIter - 1,
3157                                                      theArgVec + anArgIter + 1,
3158                                                      aChangeSet->EdgeColor);
3159       if (aNbParsed == 0)
3160       {
3161         Message::SendFail() << "Syntax error at '" << anArg << "'";
3162         return 1;
3163       }
3164       anArgIter += aNbParsed;
3165       aChangeSet->ToSetEdgeColor = 1;
3166     }
3167     else if (anArg == "-unset")
3168     {
3169       aChangeSet->ToSetVisibility = 1;
3170       aChangeSet->Visibility = 1;
3171       aChangeSet->ToSetLineWidth = -1;
3172       aChangeSet->LineWidth = 1.0;
3173       aChangeSet->ToSetTypeOfLine = -1;
3174       aChangeSet->StippleLinePattern = 0xFFFF;
3175       aChangeSet->StippleLineFactor = 1;
3176       aChangeSet->ToSetTypeOfMarker = -1;
3177       aChangeSet->TypeOfMarker = Aspect_TOM_PLUS;
3178       aChangeSet->ToSetMarkerSize = -1;
3179       aChangeSet->MarkerSize = 1.0;
3180       aChangeSet->ToSetTransparency = -1;
3181       aChangeSet->Transparency = 0.0;
3182       aChangeSet->ToSetAlphaMode = -1;
3183       aChangeSet->AlphaMode = Graphic3d_AlphaMode_BlendAuto;
3184       aChangeSet->AlphaCutoff = 0.5f;
3185       aChangeSet->ToSetColor = -1;
3186       aChangeSet->Color = DEFAULT_COLOR;
3187       //aChangeSet->ToSetBackFaceColor = -1; // should be reset by ToSetColor
3188       //aChangeSet->BackFaceColor = DEFAULT_COLOR;
3189       aChangeSet->ToSetMaterial = -1;
3190       aChangeSet->Material = Graphic3d_NOM_DEFAULT;
3191       aChangeSet->ToSetShowFreeBoundary = -1;
3192       aChangeSet->ToSetFreeBoundaryColor = -1;
3193       aChangeSet->FreeBoundaryColor = DEFAULT_FREEBOUNDARY_COLOR;
3194       aChangeSet->ToSetFreeBoundaryWidth = -1;
3195       aChangeSet->FreeBoundaryWidth = 1.0;
3196       aChangeSet->ToEnableIsoOnTriangulation = -1;
3197       //
3198       aChangeSet->ToSetFaceBoundaryDraw = -1;
3199       aChangeSet->ToSetFaceBoundaryUpperContinuity = -1;
3200       aChangeSet->FaceBoundaryUpperContinuity = GeomAbs_CN;
3201       aChangeSet->ToSetFaceBoundaryColor = -1;
3202       aChangeSet->FaceBoundaryColor = Quantity_NOC_BLACK;
3203       aChangeSet->ToSetFaceBoundaryWidth = -1;
3204       aChangeSet->FaceBoundaryWidth = 1.0f;
3205       aChangeSet->ToSetTypeOfFaceBoundaryLine = -1;
3206       aChangeSet->TypeOfFaceBoundaryLine = Aspect_TOL_SOLID;
3207       //
3208       aChangeSet->ToSetHatch = -1;
3209       aChangeSet->StdHatchStyle = -1;
3210       aChangeSet->PathToHatchPattern.Clear();
3211       aChangeSet->ToSetShadingModel = -1;
3212       aChangeSet->ShadingModel = Graphic3d_TOSM_DEFAULT;
3213       aChangeSet->ToSetInterior = -1;
3214       aChangeSet->InteriorStyle = Aspect_IS_SOLID;
3215       aChangeSet->ToSetDrawSilhouette = -1;
3216       aChangeSet->ToSetDrawEdges = -1;
3217       aChangeSet->ToSetQuadEdges = -1;
3218       aChangeSet->ToSetEdgeColor = -1;
3219       aChangeSet->EdgeColor = Quantity_ColorRGBA (DEFAULT_COLOR);
3220       aChangeSet->ToSetEdgeWidth = -1;
3221       aChangeSet->EdgeWidth = 1.0;
3222       aChangeSet->ToSetTypeOfEdge = -1;
3223       aChangeSet->TypeOfEdge = Aspect_TOL_SOLID;
3224     }
3225     else if (anArg == "-dumpjson")
3226     {
3227       toDump = Standard_True;
3228     }
3229     else if (anArg == "-dumpcompact")
3230     {
3231       toCompactDump = Standard_False;
3232       if (++anArgIter >= theArgNb && Draw::ParseOnOff (theArgVec[anArgIter + 1], toCompactDump))
3233         ++anArgIter;
3234     }
3235     else if (anArg == "-dumpdepth")
3236     {
3237       if (++anArgIter >= theArgNb)
3238       {
3239         Message::SendFail() << "Error: wrong syntax at " << anArg;
3240         return 1;
3241       }
3242       aDumpDepth = Draw::Atoi (theArgVec[anArgIter]);
3243     }
3244     else
3245     {
3246       Message::SendFail() << "Error: wrong syntax at " << anArg;
3247       return 1;
3248     }
3249   }
3250
3251   for (NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3252        aChangesIter.More(); aChangesIter.Next())
3253   {
3254     if (!aChangesIter.Value().Validate())
3255     {
3256       return 1;
3257     }
3258   }
3259
3260   // special case for -defaults parameter.
3261   // all changed values will be set to DefaultDrawer.
3262   if (isDefaults)
3263   {
3264     const Handle(Prs3d_Drawer)& aDrawer = aCtx->DefaultDrawer();
3265     aChangeSet->Apply (aDrawer);
3266     if (aChangeSet->ToSetLineWidth != 0)
3267     {
3268       aDrawer->LineAspect()->SetWidth (aChangeSet->LineWidth);
3269       aDrawer->WireAspect()->SetWidth (aChangeSet->LineWidth);
3270       aDrawer->UnFreeBoundaryAspect()->SetWidth (aChangeSet->LineWidth);
3271       aDrawer->SeenLineAspect()->SetWidth (aChangeSet->LineWidth);
3272     }
3273     if (aChangeSet->ToSetColor != 0)
3274     {
3275       aDrawer->ShadingAspect()->SetColor        (aChangeSet->Color);
3276       aDrawer->LineAspect()->SetColor           (aChangeSet->Color);
3277       aDrawer->UnFreeBoundaryAspect()->SetColor (aChangeSet->Color);
3278       aDrawer->SeenLineAspect()->SetColor       (aChangeSet->Color);
3279       aDrawer->WireAspect()->SetColor           (aChangeSet->Color);
3280       aDrawer->PointAspect()->SetColor          (aChangeSet->Color);
3281     }
3282     if (aChangeSet->ToSetTransparency != 0)
3283     {
3284       aDrawer->ShadingAspect()->SetTransparency (aChangeSet->Transparency);
3285     }
3286     if (aChangeSet->ToSetMaterial != 0)
3287     {
3288       aDrawer->ShadingAspect()->SetMaterial (aChangeSet->Material);
3289     }
3290     if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3291     {
3292       aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1);
3293     }
3294
3295     // redisplay all objects in context
3296     for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3297     {
3298       Handle(AIS_InteractiveObject)  aPrs = aPrsIter.Current();
3299       if (!aPrs.IsNull())
3300       {
3301         aCtx->Redisplay (aPrs, Standard_False);
3302       }
3303     }
3304     if (toDump)
3305     {
3306       Standard_SStream aStream;
3307       aDrawer->DumpJson (aStream, aDumpDepth);
3308
3309       if (toCompactDump)
3310         theDI << Standard_Dump::Text (aStream);
3311       else
3312         theDI << Standard_Dump::FormatJson (aStream);
3313     }
3314     return 0;
3315   }
3316
3317   for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next())
3318   {
3319     const TCollection_AsciiString& aName = aPrsIter.CurrentName();
3320     Handle(AIS_InteractiveObject)  aPrs  = aPrsIter.Current();
3321     if (aPrs.IsNull())
3322     {
3323       return 1;
3324     }
3325
3326     Handle(Prs3d_Drawer)           aDrawer = aPrs->Attributes();
3327     Handle(AIS_ColoredShape) aColoredPrs;
3328     Standard_Boolean toDisplay = Standard_False;
3329     Standard_Boolean toRedisplay = Standard_False;
3330     if (aChanges.Length() > 1 || aChangeSet->ToSetVisibility == 1)
3331     {
3332       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aPrs);
3333       if (aShapePrs.IsNull())
3334       {
3335         Message::SendFail() << "Error: an object " << aName << " is not an AIS_Shape presentation!";
3336         return 1;
3337       }
3338       aColoredPrs = Handle(AIS_ColoredShape)::DownCast (aShapePrs);
3339       if (aColoredPrs.IsNull())
3340       {
3341         aColoredPrs = new AIS_ColoredShape (aShapePrs);
3342         if (aShapePrs->HasDisplayMode())
3343         {
3344           aColoredPrs->SetDisplayMode (aShapePrs->DisplayMode());
3345         }
3346         aColoredPrs->SetLocalTransformation (aShapePrs->LocalTransformation());
3347         aCtx->Remove (aShapePrs, Standard_False);
3348         GetMapOfAIS().UnBind2 (aName);
3349         GetMapOfAIS().Bind (aColoredPrs, aName);
3350         toDisplay = Standard_True;
3351         aShapePrs = aColoredPrs;
3352         aPrs      = aColoredPrs;
3353       }
3354     }
3355
3356     if (!aPrs.IsNull())
3357     {
3358       NCollection_Sequence<ViewerTest_AspectsChangeSet>::Iterator aChangesIter (aChanges);
3359       aChangeSet = &aChangesIter.ChangeValue();
3360       if (aChangeSet->ToSetVisibility == 1)
3361       {
3362         Handle(AIS_ColoredDrawer) aColDrawer = aColoredPrs->CustomAspects (aColoredPrs->Shape());
3363         aColDrawer->SetHidden (aChangeSet->Visibility == 0);
3364       }
3365       else if (aChangeSet->ToSetMaterial == 1)
3366       {
3367         aCtx->SetMaterial (aPrs, aChangeSet->Material, Standard_False);
3368       }
3369       else if (aChangeSet->ToSetMaterial == -1)
3370       {
3371         aCtx->UnsetMaterial (aPrs, Standard_False);
3372       }
3373       if (aChangeSet->ToSetColor == 1)
3374       {
3375         aCtx->SetColor (aPrs, aChangeSet->Color, Standard_False);
3376       }
3377       else if (aChangeSet->ToSetColor == -1)
3378       {
3379         aCtx->UnsetColor (aPrs, Standard_False);
3380       }
3381       if (aChangeSet->ToSetTransparency == 1)
3382       {
3383         aCtx->SetTransparency (aPrs, aChangeSet->Transparency, Standard_False);
3384       }
3385       else if (aChangeSet->ToSetTransparency == -1)
3386       {
3387         aCtx->UnsetTransparency (aPrs, Standard_False);
3388       }
3389       if (aChangeSet->ToSetLineWidth == 1)
3390       {
3391         aCtx->SetWidth (aPrs, aChangeSet->LineWidth, Standard_False);
3392       }
3393       else if (aChangeSet->ToSetLineWidth == -1)
3394       {
3395         aCtx->UnsetWidth (aPrs, Standard_False);
3396       }
3397       else if (aChangeSet->ToEnableIsoOnTriangulation != 0)
3398       {
3399         aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs);
3400         toRedisplay = Standard_True;
3401       }
3402       else if (aChangeSet->ToSetSensitivity != 0)
3403       {
3404         aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3405       }
3406       if (!aDrawer.IsNull())
3407       {
3408         toRedisplay = aChangeSet->Apply (aDrawer) || toRedisplay;
3409       }
3410
3411       for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next())
3412       {
3413         aChangeSet = &aChangesIter.ChangeValue();
3414         for (NCollection_Sequence<TopoDS_Shape>::Iterator aSubShapeIter (aChangeSet->SubShapes);
3415              aSubShapeIter.More(); aSubShapeIter.Next())
3416         {
3417           const TopoDS_Shape& aSubShape = aSubShapeIter.Value();
3418           if (!aChangeSet->IsEmpty())
3419           {
3420             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3421             aChangeSet->Apply (aCurColDrawer);
3422           }
3423           if (aChangeSet->ToSetVisibility == 1)
3424           {
3425             Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape);
3426             aCurColDrawer->SetHidden (aChangeSet->Visibility == 0);
3427           }
3428           if (aChangeSet->ToSetColor == 1)
3429           {
3430             aColoredPrs->SetCustomColor (aSubShape, aChangeSet->Color);
3431           }
3432           if (aChangeSet->ToSetTransparency == 1)
3433           {
3434             aColoredPrs->SetCustomTransparency (aSubShape, aChangeSet->Transparency);
3435           }
3436           if (aChangeSet->ToSetLineWidth == 1)
3437           {
3438             aColoredPrs->SetCustomWidth (aSubShape, aChangeSet->LineWidth);
3439           }
3440           if (aChangeSet->ToSetColor     == -1
3441            || aChangeSet->ToSetLineWidth == -1)
3442           {
3443             aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
3444           }
3445           if (aChangeSet->ToSetSensitivity != 0)
3446           {
3447             aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
3448           }
3449         }
3450       }
3451       if (toDisplay)
3452       {
3453         aCtx->Display (aPrs, Standard_False);
3454       }
3455       if (toRedisplay)
3456       {
3457         aCtx->Redisplay (aPrs, Standard_False);
3458       }
3459       else if (!aColoredPrs.IsNull())
3460       {
3461         aCtx->Redisplay (aColoredPrs, Standard_False);
3462       }
3463       else
3464       {
3465         aPrs->SynchronizeAspects();
3466       }
3467
3468       if (toDump)
3469       {
3470         Standard_SStream aStream;
3471         aDrawer->DumpJson (aStream);
3472
3473         theDI << aName << ": \n";
3474         theDI << Standard_Dump::FormatJson (aStream);
3475         theDI << "\n";
3476       }
3477     }
3478   }
3479   return 0;
3480 }
3481
3482 //==============================================================================
3483 //function : VDonly2
3484 //author   : ege
3485 //purpose  : Display only a selected or named  object
3486 //           if there is no selected or named object s, nothing is done
3487 //==============================================================================
3488 static int VDonly2 (Draw_Interpretor& ,
3489                     Standard_Integer  theArgNb,
3490                     const char**      theArgVec)
3491 {
3492   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3493   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3494   if (aCtx.IsNull())
3495   {
3496     Message::SendFail ("Error: no active view!");
3497     return 1;
3498   }
3499
3500   Standard_Integer anArgIter = 1;
3501   for (; anArgIter < theArgNb; ++anArgIter)
3502   {
3503     if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3504     {
3505       break;
3506     }
3507   }
3508
3509   NCollection_Map<Handle(Standard_Transient)> aDispSet;
3510   if (anArgIter >= theArgNb)
3511   {
3512     // display only selected objects
3513     if (aCtx->NbSelected() < 1)
3514     {
3515       return 0;
3516     }
3517
3518     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
3519     {
3520       aDispSet.Add (aCtx->SelectedInteractive());
3521     }
3522   }
3523   else
3524   {
3525     // display only specified objects
3526     for (; anArgIter < theArgNb; ++anArgIter)
3527     {
3528       TCollection_AsciiString aName = theArgVec[anArgIter];
3529       Handle(AIS_InteractiveObject) aShape;
3530       if (GetMapOfAIS().Find2 (aName, aShape)
3531       && !aShape.IsNull())
3532       {
3533         aCtx->Display (aShape, Standard_False);
3534         aDispSet.Add (aShape);
3535       }
3536     }
3537   }
3538
3539   // weed out other objects
3540   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); anIter.More(); anIter.Next())
3541   {
3542     if (aDispSet.Contains (anIter.Key1()))
3543     {
3544       continue;
3545     }
3546
3547     if (Handle(AIS_InteractiveObject) aShape = anIter.Key1())
3548     {
3549       aCtx->Erase (aShape, Standard_False);
3550     }
3551   }
3552   return 0;
3553 }
3554
3555 //==============================================================================
3556 //function : VRemove
3557 //purpose  : Removes selected or named objects.
3558 //           If there is no selected or named objects,
3559 //           all objects in the viewer can be removed with argument -all.
3560 //           If -context is in arguments, the object is not deleted from the map of
3561 //           objects (deleted only from the current context).
3562 //==============================================================================
3563 int VRemove (Draw_Interpretor& theDI,
3564              Standard_Integer  theArgNb,
3565              const char**      theArgVec)
3566 {
3567   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3568   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3569   if (aCtx.IsNull())
3570   {
3571     Message::SendFail ("Error: no active view!");
3572     return 1;
3573   }
3574
3575   Standard_Boolean isContextOnly = Standard_False;
3576   Standard_Boolean toRemoveAll   = Standard_False;
3577   Standard_Boolean toPrintInfo   = Standard_True;
3578   Standard_Boolean toFailOnError = Standard_True;
3579
3580   Standard_Integer anArgIter = 1;
3581   for (; anArgIter < theArgNb; ++anArgIter)
3582   {
3583     TCollection_AsciiString anArg = theArgVec[anArgIter];
3584     anArg.LowerCase();
3585     if (anArg == "-context")
3586     {
3587       isContextOnly = Standard_True;
3588     }
3589     else if (anArg == "-all")
3590     {
3591       toRemoveAll = Standard_True;
3592     }
3593     else if (anArg == "-noinfo")
3594     {
3595       toPrintInfo = Standard_False;
3596     }
3597     else if (anArg == "-noerror"
3598           || anArg == "-nofail")
3599     {
3600       toFailOnError = Standard_False;
3601     }
3602     else if (anUpdateTool.parseRedrawMode (anArg))
3603     {
3604       continue;
3605     }
3606     else
3607     {
3608       break;
3609     }
3610   }
3611   if (toRemoveAll
3612    && anArgIter < theArgNb)
3613   {
3614     Message::SendFail ("Error: wrong syntax!");
3615     return 1;
3616   }
3617
3618   NCollection_List<TCollection_AsciiString> anIONameList;
3619   if (toRemoveAll)
3620   {
3621     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3622          anIter.More(); anIter.Next())
3623     {
3624       anIONameList.Append (anIter.Key2());
3625     }
3626   }
3627   else if (anArgIter < theArgNb) // removed objects names are in argument list
3628   {
3629     for (; anArgIter < theArgNb; ++anArgIter)
3630     {
3631       const TCollection_AsciiString aName (theArgVec[anArgIter]);
3632       if (aName.Search ("*") != -1)
3633       {
3634         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3635         {
3636           if (aPrsIter.Key1()->GetContext() != aCtx)
3637           {
3638             continue;
3639           }
3640           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3641           if (theDI.Eval (aCheck.ToCString()) == 0
3642           && *theDI.Result() == '1')
3643           {
3644             anIONameList.Append (aPrsIter.Key2());
3645           }
3646         }
3647         theDI.Reset();
3648         continue;
3649       }
3650
3651       Handle(AIS_InteractiveObject) anIO;
3652       if (!GetMapOfAIS().Find2 (aName, anIO))
3653       {
3654         if (toFailOnError)
3655         {
3656           Message::SendFail() << "Syntax error: '" << aName << "' was not bound to some object.";
3657           return 1;
3658         }
3659       }
3660       else if (anIO->GetContext() != aCtx)
3661       {
3662         if (toFailOnError)
3663         {
3664           Message::SendFail() << "Syntax error: '" << aName << "' was not displayed in current context.\n"
3665                               << "Please activate view with this object displayed and try again.";
3666           return 1;
3667         }
3668       }
3669       else
3670       {
3671         anIONameList.Append (aName);
3672       }
3673     }
3674   }
3675   else if (aCtx->NbSelected() > 0)
3676   {
3677     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3678          anIter.More(); anIter.Next())
3679     {
3680       if (!aCtx->IsSelected (anIter.Key1()))
3681       {
3682         continue;
3683       }
3684
3685       anIONameList.Append (anIter.Key2());
3686       continue;
3687     }
3688   }
3689
3690   // Unbind all removed objects from the map of displayed IO.
3691   for (NCollection_List<TCollection_AsciiString>::Iterator anIter (anIONameList);
3692        anIter.More(); anIter.Next())
3693   {
3694     const Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (anIter.Value());
3695     aCtx->Remove (anIO, Standard_False);
3696     if (toPrintInfo)
3697     {
3698       theDI << anIter.Value() << " ";
3699     }
3700     if (!isContextOnly)
3701     {
3702       GetMapOfAIS().UnBind2 (anIter.Value());
3703     }
3704   }
3705   return 0;
3706 }
3707
3708 //==============================================================================
3709 //function : VErase
3710 //purpose  : Erase some selected or named objects
3711 //           if there is no selected or named objects, the whole viewer is erased
3712 //==============================================================================
3713 int VErase (Draw_Interpretor& theDI,
3714             Standard_Integer  theArgNb,
3715             const char**      theArgVec)
3716 {
3717   const Handle(AIS_InteractiveContext)& aCtx  = ViewerTest::GetAISContext();
3718   const Handle(V3d_View)&               aView = ViewerTest::CurrentView();
3719   ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
3720   if (aCtx.IsNull())
3721   {
3722     Message::SendFail ("Error: no active view!");
3723     return 1;
3724   }
3725
3726   const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall";
3727
3728   Standard_Integer anArgIter = 1;
3729   Standard_Boolean toEraseInView = Standard_False;
3730   Standard_Boolean toFailOnError = Standard_True;
3731   TColStd_SequenceOfAsciiString aNamesOfEraseIO;
3732   for (; anArgIter < theArgNb; ++anArgIter)
3733   {
3734     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3735     anArgCase.LowerCase();
3736     if (anUpdateTool.parseRedrawMode (anArgCase))
3737     {
3738       continue;
3739     }
3740     else if (anArgCase == "-view"
3741           || anArgCase == "-inview")
3742     {
3743       toEraseInView = Standard_True;
3744     }
3745     else if (anArgCase == "-noerror"
3746           || anArgCase == "-nofail")
3747     {
3748       toFailOnError = Standard_False;
3749     }
3750     else
3751     {
3752       aNamesOfEraseIO.Append (theArgVec[anArgIter]);
3753     }
3754   }
3755
3756   if (!aNamesOfEraseIO.IsEmpty() && toEraseAll)
3757   {
3758     Message::SendFail() << "Error: wrong syntax, " << theArgVec[0] << " too much arguments.";
3759     return 1;
3760   }
3761
3762   if (!aNamesOfEraseIO.IsEmpty())
3763   {
3764     // Erase named objects
3765     NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString> aPrsList;
3766     for (TColStd_SequenceOfAsciiString::Iterator anIter (aNamesOfEraseIO); anIter.More(); anIter.Next())
3767     {
3768       const TCollection_AsciiString& aName = anIter.Value();
3769       if (aName.Search ("*") != -1)
3770       {
3771         for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aPrsIter (GetMapOfAIS()); aPrsIter.More(); aPrsIter.Next())
3772         {
3773           const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match '") + aName + "' '" + aPrsIter.Key2() + "'";
3774           if (theDI.Eval (aCheck.ToCString()) == 0
3775           && *theDI.Result() == '1')
3776           {
3777             aPrsList.Add (aPrsIter.Key1(), aPrsIter.Key2());
3778           }
3779         }
3780         theDI.Reset();
3781       }
3782       else
3783       {
3784         Handle(AIS_InteractiveObject) anIO;
3785         if (!GetMapOfAIS().Find2 (aName, anIO))
3786         {
3787           if (toFailOnError)
3788           {
3789             Message::SendFail() << "Syntax error: '" << aName << "' is not found";
3790             return 1;
3791           }
3792         }
3793         else
3794         {
3795           aPrsList.Add (anIO, aName);
3796         }
3797       }
3798     }
3799
3800     for (NCollection_IndexedDataMap<Handle(AIS_InteractiveObject), TCollection_AsciiString>::Iterator anIter (aPrsList); anIter.More(); anIter.Next())
3801     {
3802       theDI << anIter.Value() << " ";
3803       if (toEraseInView)
3804       {
3805         aCtx->SetViewAffinity (anIter.Key(), aView, Standard_False);
3806       }
3807       else
3808       {
3809         aCtx->Erase (anIter.Key(), Standard_False);
3810       }
3811     }
3812   }
3813   else if (!toEraseAll && aCtx->NbSelected() > 0)
3814   {
3815     // Erase selected objects
3816     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3817          anIter.More(); anIter.Next())
3818     {
3819       const Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3820       if (!anIO.IsNull()
3821        && aCtx->IsSelected (anIO))
3822       {
3823         theDI << anIter.Key2() << " ";
3824         if (toEraseInView)
3825         {
3826           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3827         }
3828       }
3829     }
3830
3831     if (!toEraseInView)
3832     {
3833       aCtx->EraseSelected (Standard_False);
3834     }
3835   }
3836   else
3837   {
3838     // Erase all objects
3839     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3840          anIter.More(); anIter.Next())
3841     {
3842       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
3843       if (!anIO.IsNull())
3844       {
3845         if (toEraseInView)
3846         {
3847           aCtx->SetViewAffinity (anIO, aView, Standard_False);
3848         }
3849         else
3850         {
3851           aCtx->Erase (anIO, Standard_False);
3852         }
3853       }
3854     }
3855   }
3856
3857   return 0;
3858 }
3859
3860 //==============================================================================
3861 //function : VDisplayAll
3862 //purpose  : Display all the objects of the Map
3863 //==============================================================================
3864 static int VDisplayAll (Draw_Interpretor& ,
3865                         Standard_Integer  theArgNb,
3866                         const char**      theArgVec)
3867
3868 {
3869   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
3870   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3871   if (aCtx.IsNull())
3872   {
3873     Message::SendFail ("Error: no active view!");
3874     return 1;
3875   }
3876
3877   Standard_Integer anArgIter = 1;
3878   for (; anArgIter < theArgNb; ++anArgIter)
3879   {
3880     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3881     anArgCase.LowerCase();
3882     if (anUpdateTool.parseRedrawMode (anArgCase))
3883     {
3884       continue;
3885     }
3886     else
3887     {
3888       break;
3889     }
3890   }
3891   if (anArgIter < theArgNb)
3892   {
3893     Message::SendFail() << theArgVec[0] << "Error: wrong syntax";
3894     return 1;
3895   }
3896
3897   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3898        anIter.More(); anIter.Next())
3899   {
3900     aCtx->Erase (anIter.Key1(), Standard_False);
3901   }
3902
3903   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
3904        anIter.More(); anIter.Next())
3905   {
3906     aCtx->Display (anIter.Key1(), Standard_False);
3907   }
3908   return 0;
3909 }
3910
3911 //! Auxiliary method to check if presentation exists
3912 inline Standard_Integer checkMode (const Handle(AIS_InteractiveContext)& theCtx,
3913                                    const Handle(AIS_InteractiveObject)&  theIO,
3914                                    const Standard_Integer                theMode)
3915 {
3916   if (theIO.IsNull() || theCtx.IsNull())
3917   {
3918     return -1;
3919   }
3920
3921   if (theMode != -1)
3922   {
3923     if (theCtx->MainPrsMgr()->HasPresentation (theIO, theMode))
3924     {
3925       return theMode;
3926     }
3927   }
3928   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theIO->DisplayMode()))
3929   {
3930     return theIO->DisplayMode();
3931   }
3932   else if (theCtx->MainPrsMgr()->HasPresentation (theIO, theCtx->DisplayMode()))
3933   {
3934     return theCtx->DisplayMode();
3935   }
3936
3937   return -1;
3938 }
3939
3940 enum ViewerTest_BndAction
3941 {
3942   BndAction_Hide,
3943   BndAction_Show,
3944   BndAction_Print
3945 };
3946
3947 //! Auxiliary method to print bounding box of presentation
3948 inline void bndPresentation (Draw_Interpretor&                         theDI,
3949                              const Handle(PrsMgr_PresentationManager)& theMgr,
3950                              const Handle(AIS_InteractiveObject)&      theObj,
3951                              const Standard_Integer                    theDispMode,
3952                              const TCollection_AsciiString&            theName,
3953                              const ViewerTest_BndAction                theAction,
3954                              const Handle(Prs3d_Drawer)&               theStyle)
3955 {
3956   switch (theAction)
3957   {
3958     case BndAction_Hide:
3959     {
3960       theMgr->Unhighlight (theObj);
3961       break;
3962     }
3963     case BndAction_Show:
3964     {
3965       theMgr->Color (theObj, theStyle, theDispMode);
3966       break;
3967     }
3968     case BndAction_Print:
3969     {
3970       Bnd_Box aBox;
3971       for (PrsMgr_Presentations::Iterator aPrsIter (theObj->Presentations()); aPrsIter.More(); aPrsIter.Next())
3972       {
3973         if (aPrsIter.Value()->Mode() != theDispMode)
3974           continue;
3975
3976         aBox = aPrsIter.Value()->MinMaxValues();
3977       }
3978       gp_Pnt aMin = aBox.CornerMin();
3979       gp_Pnt aMax = aBox.CornerMax();
3980       theDI << theName  << "\n"
3981             << aMin.X() << " " << aMin.Y() << " " << aMin.Z() << " "
3982             << aMax.X() << " " << aMax.Y() << " " << aMax.Z() << "\n";
3983       break;
3984     }
3985   }
3986 }
3987
3988 //==============================================================================
3989 //function : VBounding
3990 //purpose  :
3991 //==============================================================================
3992 int VBounding (Draw_Interpretor& theDI,
3993                Standard_Integer  theArgNb,
3994                const char**      theArgVec)
3995 {
3996   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
3997   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
3998   if (aCtx.IsNull())
3999   {
4000     Message::SendFail ("Error: no active view!");
4001     return 1;
4002   }
4003
4004   ViewerTest_BndAction anAction = BndAction_Show;
4005   Standard_Integer     aMode    = -1;
4006
4007   Handle(Prs3d_Drawer) aStyle;
4008
4009   Standard_Integer anArgIter = 1;
4010   for (; anArgIter < theArgNb; ++anArgIter)
4011   {
4012     TCollection_AsciiString anArg (theArgVec[anArgIter]);
4013     anArg.LowerCase();
4014     if (anArg == "-print")
4015     {
4016       anAction = BndAction_Print;
4017     }
4018     else if (anArg == "-show")
4019     {
4020       anAction = BndAction_Show;
4021     }
4022     else if (anArg == "-hide")
4023     {
4024       anAction = BndAction_Hide;
4025     }
4026     else if (anArg == "-mode")
4027     {
4028       if (++anArgIter >= theArgNb)
4029       {
4030         Message::SendFail() << "Error: wrong syntax at " << anArg;
4031         return 1;
4032       }
4033       aMode = Draw::Atoi (theArgVec[anArgIter]);
4034     }
4035     else if (!anUpdateTool.parseRedrawMode (anArg))
4036     {
4037       break;
4038     }
4039   }
4040
4041   if (anAction == BndAction_Show)
4042   {
4043     aStyle = new Prs3d_Drawer();
4044     aStyle->SetMethod (Aspect_TOHM_BOUNDBOX);
4045     aStyle->SetColor  (Quantity_NOC_GRAY99);
4046   }
4047
4048   Standard_Integer aHighlightedMode = -1;
4049   if (anArgIter < theArgNb)
4050   {
4051     // has a list of names
4052     for (; anArgIter < theArgNb; ++anArgIter)
4053     {
4054       TCollection_AsciiString aName = theArgVec[anArgIter];
4055       Handle(AIS_InteractiveObject) anIO;
4056       if (!GetMapOfAIS().Find2 (aName, anIO))
4057       {
4058         Message::SendFail() << "Error: presentation " << aName << " does not exist";
4059         return 1;
4060       }
4061
4062       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4063       if (aHighlightedMode == -1)
4064       {
4065         Message::SendFail() << "Error: object " << aName << " has no presentation with mode " << aMode;
4066         return 1;
4067       }
4068       bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, aName, anAction, aStyle);
4069     }
4070   }
4071   else if (aCtx->NbSelected() > 0)
4072   {
4073     // remove all currently selected objects
4074     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
4075     {
4076       Handle(AIS_InteractiveObject) anIO = aCtx->SelectedInteractive();
4077       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4078       if (aHighlightedMode != -1)
4079       {
4080         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode,
4081           GetMapOfAIS().IsBound1 (anIO) ? GetMapOfAIS().Find1 (anIO) : "", anAction, aStyle);
4082       }
4083     }
4084   }
4085   else
4086   {
4087     // all objects
4088     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS());
4089          anIter.More(); anIter.Next())
4090     {
4091       Handle(AIS_InteractiveObject) anIO = anIter.Key1();
4092       aHighlightedMode = checkMode (aCtx, anIO, aMode);
4093       if (aHighlightedMode != -1)
4094       {
4095         bndPresentation (theDI, aCtx->MainPrsMgr(), anIO, aHighlightedMode, anIter.Key2(), anAction, aStyle);
4096       }
4097     }
4098   }
4099   return 0;
4100 }
4101
4102 //==============================================================================
4103 //function : VTexture
4104 //purpose  :
4105 //==============================================================================
4106 Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4107 {
4108   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
4109   if (aCtx.IsNull())
4110   {
4111     Message::SendFail() << "Error: no active view!";
4112     return 1;
4113   }
4114
4115   int  toModulate     = -1;
4116   bool toSetFilter    = false;
4117   bool toSetAniso     = false;
4118   bool toSetTrsfAngle = false;
4119   bool toSetTrsfTrans = false;
4120   bool toSetTrsfScale = false;
4121   Standard_ShortReal aTrsfRotAngle = 0.0f;
4122   Graphic3d_Vec2 aTrsfTrans (0.0f, 0.0f);
4123   Graphic3d_Vec2 aTrsfScale (1.0f, 1.0f);
4124   Graphic3d_TypeOfTextureFilter      aFilter       = Graphic3d_TOTF_NEAREST;
4125   Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
4126
4127   Handle(AIS_InteractiveObject) aTexturedIO;
4128   Handle(AIS_Shape) aTexturedShape;
4129   Handle(Graphic3d_TextureSet) aTextureSetOld;
4130   NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
4131   bool toSetGenRepeat = false;
4132   bool toSetGenScale  = false;
4133   bool toSetGenOrigin = false;
4134   bool toSetImage     = false;
4135   bool toComputeUV    = false;
4136
4137   const TCollection_AsciiString aCommandName (theArgVec[0]);
4138   bool toSetDefaults = aCommandName == "vtexdefault";
4139
4140   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4141   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
4142   {
4143     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4144     TCollection_AsciiString       aNameCase = aName;
4145     aNameCase.LowerCase();
4146     if (anUpdateTool.parseRedrawMode (aName))
4147     {
4148       continue;
4149     }
4150     else if (aTexturedIO.IsNull())
4151     {
4152       const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfIO = GetMapOfAIS();
4153       if (aMapOfIO.IsBound2 (aName))
4154       {
4155         aTexturedIO = aMapOfIO.Find2 (aName);
4156         aTexturedShape = Handle(AIS_Shape)::DownCast (aTexturedIO);
4157       }
4158       if (aTexturedIO.IsNull())
4159       {
4160         Message::SendFail() << "Syntax error: shape " << aName << " does not exists in the viewer.";
4161         return 1;
4162       }
4163
4164       if (aTexturedIO->Attributes()->HasOwnShadingAspect())
4165       {
4166         aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
4167       }
4168     }
4169     else if (!aTexturedShape.IsNull()
4170           && (aNameCase == "-scale"
4171            || aNameCase == "-setscale"
4172            || aCommandName == "vtexscale"))
4173     {
4174       if (aCommandName != "vtexscale")
4175       {
4176         ++anArgIter;
4177       }
4178       if (anArgIter < theArgsNb)
4179       {
4180         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4181         TCollection_AsciiString aValUCase = aValU;
4182         aValUCase.LowerCase();
4183         toSetGenScale = true;
4184         if (aValUCase == "off")
4185         {
4186           aTexturedShape->SetTextureScaleUV (gp_Pnt2d (1.0, 1.0));
4187           continue;
4188         }
4189         else if (anArgIter + 1 < theArgsNb)
4190         {
4191           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4192           if (aValU.IsRealValue()
4193            && aValV.IsRealValue())
4194           {
4195             aTexturedShape->SetTextureScaleUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4196             ++anArgIter;
4197             continue;
4198           }
4199         }
4200       }
4201       Message::SendFail() << "Syntax error: unexpected argument '" << aName << "'";
4202       return 1;
4203     }
4204     else if (!aTexturedShape.IsNull()
4205           && (aNameCase == "-origin"
4206            || aNameCase == "-setorigin"
4207            || aCommandName == "vtexorigin"))
4208     {
4209       if (aCommandName != "vtexorigin")
4210       {
4211         ++anArgIter;
4212       }
4213       if (anArgIter < theArgsNb)
4214       {
4215         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4216         TCollection_AsciiString aValUCase = aValU;
4217         aValUCase.LowerCase();
4218         toSetGenOrigin = true;
4219         if (aValUCase == "off")
4220         {
4221           aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4222           continue;
4223         }
4224         else if (anArgIter + 1 < theArgsNb)
4225         {
4226           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4227           if (aValU.IsRealValue()
4228            && aValV.IsRealValue())
4229           {
4230             aTexturedShape->SetTextureOriginUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4231             ++anArgIter;
4232             continue;
4233           }
4234         }
4235       }
4236       Message::SendFail() << "Syntax error: unexpected argument '" << aName << "'";
4237       return 1;
4238     }
4239     else if (!aTexturedShape.IsNull()
4240           && (aNameCase == "-repeat"
4241            || aNameCase == "-setrepeat"
4242            || aCommandName == "vtexrepeat"))
4243     {
4244       if (aCommandName != "vtexrepeat")
4245       {
4246         ++anArgIter;
4247       }
4248       if (anArgIter < theArgsNb)
4249       {
4250         TCollection_AsciiString aValU (theArgVec[anArgIter]);
4251         TCollection_AsciiString aValUCase = aValU;
4252         aValUCase.LowerCase();
4253         toSetGenRepeat = true;
4254         if (aValUCase == "off")
4255         {
4256           aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4257           continue;
4258         }
4259         else if (anArgIter + 1 < theArgsNb)
4260         {
4261           TCollection_AsciiString aValV (theArgVec[anArgIter + 1]);
4262           if (aValU.IsRealValue()
4263            && aValV.IsRealValue())
4264           {
4265             aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (aValU.RealValue(), aValV.RealValue()));
4266             ++anArgIter;
4267             continue;
4268           }
4269         }
4270       }
4271       Message::SendFail() << "Syntax error: unexpected argument '" << aName << "'";
4272       return 1;
4273     }
4274     else if (aNameCase == "-modulate")
4275     {
4276       bool toModulateBool = true;
4277       if (anArgIter + 1 < theArgsNb
4278        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toModulateBool))
4279       {
4280         ++anArgIter;
4281       }
4282       toModulate = toModulateBool ? 1 : 0;
4283     }
4284     else if ((aNameCase == "-setfilter"
4285            || aNameCase == "-filter")
4286            && anArgIter + 1 < theArgsNb)
4287     {
4288       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4289       aValue.LowerCase();
4290       ++anArgIter;
4291       toSetFilter = true;
4292       if (aValue == "nearest")
4293       {
4294         aFilter = Graphic3d_TOTF_NEAREST;
4295       }
4296       else if (aValue == "bilinear")
4297       {
4298         aFilter = Graphic3d_TOTF_BILINEAR;
4299       }
4300       else if (aValue == "trilinear")
4301       {
4302         aFilter = Graphic3d_TOTF_TRILINEAR;
4303       }
4304       else
4305       {
4306         Message::SendFail() << "Syntax error: unexpected argument '" << aValue << "'";
4307         return 1;
4308       }
4309     }
4310     else if ((aNameCase == "-setaniso"
4311            || aNameCase == "-setanisofilter"
4312            || aNameCase == "-aniso"
4313            || aNameCase == "-anisofilter")
4314            && anArgIter + 1 < theArgsNb)
4315     {
4316       TCollection_AsciiString aValue (theArgVec[anArgIter + 1]);
4317       aValue.LowerCase();
4318       ++anArgIter;
4319       toSetAniso = true;
4320       if (aValue == "off")
4321       {
4322         anAnisoFilter = Graphic3d_LOTA_OFF;
4323       }
4324       else if (aValue == "fast")
4325       {
4326         anAnisoFilter = Graphic3d_LOTA_FAST;
4327       }
4328       else if (aValue == "middle")
4329       {
4330         anAnisoFilter = Graphic3d_LOTA_MIDDLE;
4331       }
4332       else if (aValue == "quality"
4333             || aValue == "high")
4334       {
4335         anAnisoFilter =  Graphic3d_LOTA_QUALITY;
4336       }
4337       else
4338       {
4339         Message::SendFail() << "Syntax error: unexpected argument '" << aValue << "'";
4340         return 1;
4341       }
4342     }
4343     else if ((aNameCase == "-rotateangle"
4344            || aNameCase == "-rotangle"
4345            || aNameCase == "-rotate"
4346            || aNameCase == "-angle"
4347            || aNameCase == "-trsfangle")
4348            && anArgIter + 1 < theArgsNb)
4349     {
4350       aTrsfRotAngle  = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4351       toSetTrsfAngle = true;
4352       ++anArgIter;
4353     }
4354     else if ((aNameCase == "-trsftrans"
4355            || aNameCase == "-trsftranslate"
4356            || aNameCase == "-translate"
4357            || aNameCase == "-translation")
4358            && anArgIter + 2 < theArgsNb)
4359     {
4360       aTrsfTrans.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4361       aTrsfTrans.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4362       toSetTrsfTrans = true;
4363       anArgIter += 2;
4364     }
4365     else if ((aNameCase == "-trsfscale")
4366            && anArgIter + 2 < theArgsNb)
4367     {
4368       aTrsfScale.x() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 1]));
4369       aTrsfScale.y() = Standard_ShortReal (Draw::Atof (theArgVec[anArgIter + 2]));
4370       toSetTrsfScale = true;
4371       anArgIter += 2;
4372     }
4373     else if (aNameCase == "-default"
4374           || aNameCase == "-defaults")
4375     {
4376       toSetDefaults = true;
4377     }
4378     else if ((aNameCase == "-video")
4379            && anArgIter + 1 < theArgsNb)
4380     {
4381       const TCollection_AsciiString anInput (theArgVec[++anArgIter]);
4382       Handle(Graphic3d_MediaTextureSet) aMedia = Handle(Graphic3d_MediaTextureSet)::DownCast (aTextureSetOld);
4383       if (aMedia.IsNull())
4384       {
4385         aMedia = new Graphic3d_MediaTextureSet();
4386       }
4387       if (aMedia->Input() != anInput)
4388       {
4389         aMedia->OpenInput (anInput, false);
4390       }
4391       else
4392       {
4393         if (aMedia->SwapFrames()
4394         && !aCtx->CurrentViewer()->ZLayerSettings (aTexturedIO->ZLayer()).IsImmediate())
4395         {
4396           ViewerTest::CurrentView()->Invalidate();
4397         }
4398       }
4399       if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4400        && aTexturedShape.IsNull())
4401       {
4402         aTexturedIO->SetToUpdate();
4403       }
4404
4405       toComputeUV = aTextureSetOld.IsNull();
4406       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (true);
4407       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aMedia);
4408       aTextureSetOld.Nullify();
4409     }
4410     else if (aCommandName == "vtexture"
4411           && (aTextureVecNew.IsEmpty()
4412            || aNameCase.StartsWith ("-tex")))
4413     {
4414       Standard_Integer aTexIndex = 0;
4415       TCollection_AsciiString aTexName = aName;
4416       if (aNameCase.StartsWith ("-tex"))
4417       {
4418         if (anArgIter + 1 >= theArgsNb
4419          || aNameCase.Length() < 5)
4420         {
4421           Message::SendFail() << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'";
4422           return 1;
4423         }
4424
4425         TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
4426         if (!aTexIndexStr.IsIntegerValue())
4427         {
4428           Message::SendFail() << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'";
4429           return 1;
4430         }
4431
4432         aTexIndex = aTexIndexStr.IntegerValue();
4433         aTexName  = theArgVec[anArgIter + 1];
4434         ++anArgIter;
4435       }
4436       if (aTexIndex >= Graphic3d_TextureUnit_NB
4437        || aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
4438       {
4439         Message::SendFail ("Error: too many textures specified");
4440         return 1;
4441       }
4442
4443       toSetImage = true;
4444       if (aTexName.IsIntegerValue())
4445       {
4446         const Standard_Integer aValue = aTexName.IntegerValue();
4447         if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
4448         {
4449           Message::SendFail() << "Syntax error: texture with ID " << aValue << " is undefined!";
4450           return 1;
4451         }
4452         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
4453       }
4454       else if (aTexName == "?")
4455       {
4456         const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
4457
4458         theDi << "\n Files in current directory : \n\n";
4459         theDi.Eval ("glob -nocomplain *");
4460
4461         TCollection_AsciiString aCmnd ("glob -nocomplain ");
4462         aCmnd += aTextureFolder;
4463         aCmnd += "/* ";
4464
4465         theDi << "Files in " << aTextureFolder << " : \n\n";
4466         theDi.Eval (aCmnd.ToCString());
4467         return 0;
4468       }
4469       else if (aTexName != "off")
4470       {
4471         if (!OSD_File (aTexName).Exists())
4472         {
4473           Message::SendFail() << "Syntax error: non-existing image file has been specified '" << aTexName << "'.";
4474           return 1;
4475         }
4476         aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
4477       }
4478       else
4479       {
4480         aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
4481       }
4482
4483       if (aTextureVecNew.Value (aTexIndex))
4484       {
4485         aTextureVecNew.ChangeValue(aTexIndex)->GetParams()->SetTextureUnit((Graphic3d_TextureUnit)aTexIndex);
4486       }
4487     }
4488     else
4489     {
4490       Message::SendFail() << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'";
4491       return 1;
4492     }
4493   }
4494
4495   if (toSetImage)
4496   {
4497     // check if new image set is equal to already set one
4498     Standard_Integer aNbChanged = 0;
4499     Handle(Graphic3d_TextureSet) aTextureSetNew;
4500     if (!aTextureVecNew.IsEmpty())
4501     {
4502       aNbChanged = aTextureVecNew.Size();
4503       aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
4504       for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
4505       {
4506         Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
4507         Handle(Graphic3d_TextureRoot) aTextureOld;
4508         if (!aTextureSetOld.IsNull()
4509           && aTexIter < aTextureSetOld->Size())
4510         {
4511           aTextureOld = aTextureSetOld->Value (aTexIter);
4512         }
4513
4514         if (!aTextureOld.IsNull()
4515          && !aTextureNew.IsNull())
4516         {
4517           *aTextureNew->GetParams() = *aTextureOld->GetParams();
4518           if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
4519           {
4520             TCollection_AsciiString aFilePathOld, aFilePathNew;
4521             aTextureOld->Path().SystemName (aFilePathOld);
4522             aTextureNew->Path().SystemName (aFilePathNew);
4523             if (aTextureNew->Name() == anOldManualTex->Name()
4524              && aFilePathOld == aFilePathNew
4525              && (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
4526             {
4527               --aNbChanged;
4528               aTextureNew = anOldManualTex;
4529             }
4530           }
4531         }
4532         aTextureSetNew->SetValue (aTexIter, aTextureNew);
4533       }
4534     }
4535     if (aNbChanged == 0
4536      && ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
4537       || (aTextureSetOld->Size() == aTextureSetNew->Size())))
4538     {
4539       aTextureSetNew = aTextureSetOld;
4540     }
4541
4542     if (aTexturedIO->Attributes()->SetupOwnShadingAspect (aCtx->DefaultDrawer())
4543      && aTexturedShape.IsNull())
4544     {
4545       aTexturedIO->SetToUpdate();
4546     }
4547
4548     toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
4549     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
4550     aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
4551     aTextureSetOld.Nullify();
4552   }
4553
4554   if (toSetDefaults)
4555   {
4556     if (toModulate != -1)
4557     {
4558       toModulate = 1;
4559     }
4560     if (!toSetFilter)
4561     {
4562       toSetFilter = true;
4563       aFilter     = Graphic3d_TOTF_BILINEAR;
4564     }
4565     if (!toSetAniso)
4566     {
4567       toSetAniso    = true;
4568       anAnisoFilter = Graphic3d_LOTA_OFF;
4569     }
4570     if (!toSetTrsfAngle)
4571     {
4572       toSetTrsfAngle = true;
4573       aTrsfRotAngle  = 0.0f;
4574     }
4575     if (!toSetTrsfTrans)
4576     {
4577       toSetTrsfTrans = true;
4578       aTrsfTrans = Graphic3d_Vec2 (0.0f, 0.0f);
4579     }
4580     if (!toSetTrsfScale)
4581     {
4582       toSetTrsfScale = true;
4583       aTrsfScale = Graphic3d_Vec2 (1.0f, 1.0f);
4584     }
4585   }
4586
4587   if (aCommandName == "vtexture"
4588    && theArgsNb == 2)
4589   {
4590     if (!aTextureSetOld.IsNull())
4591     {
4592       //toComputeUV = true; // we can keep UV vertex attributes
4593       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
4594       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
4595       aTextureSetOld.Nullify();
4596     }
4597   }
4598
4599   if (aTexturedIO->Attributes()->HasOwnShadingAspect()
4600   && !aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap().IsNull())
4601   {
4602     if (toModulate != -1)
4603     {
4604       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetModulate (toModulate == 1);
4605     }
4606     if (toSetTrsfAngle)
4607     {
4608       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetRotation (aTrsfRotAngle); // takes degrees
4609     }
4610     if (toSetTrsfTrans)
4611     {
4612       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetTranslation (aTrsfTrans);
4613     }
4614     if (toSetTrsfScale)
4615     {
4616       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetScale (aTrsfScale);
4617     }
4618     if (toSetFilter)
4619     {
4620       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetFilter (aFilter);
4621     }
4622     if (toSetAniso)
4623     {
4624       aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap()->GetParams()->SetAnisoFilter (anAnisoFilter);
4625     }
4626   }
4627
4628   // set default values if requested
4629   if (!toSetGenRepeat
4630    && (aCommandName == "vtexrepeat"
4631     || toSetDefaults))
4632   {
4633     if (!aTexturedShape.IsNull())
4634     {
4635       aTexturedShape->SetTextureRepeatUV (gp_Pnt2d (1.0, 1.0));
4636     }
4637     toSetGenRepeat = true;
4638   }
4639   if (!toSetGenOrigin
4640    && (aCommandName == "vtexorigin"
4641     || toSetDefaults))
4642   {
4643     if (!aTexturedShape.IsNull())
4644     {
4645       aTexturedShape->SetTextureOriginUV (gp_Pnt2d (0.0, 0.0));
4646     }
4647     toSetGenOrigin = true;
4648   }
4649   if (!toSetGenScale
4650    && (aCommandName == "vtexscale"
4651     || toSetDefaults))
4652   {
4653     if (!aTexturedShape.IsNull())
4654     {
4655       aTexturedShape->SetTextureScaleUV  (gp_Pnt2d (1.0, 1.0));
4656     }
4657     toSetGenScale = true;
4658   }
4659
4660   if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
4661   {
4662     if (!aTexturedShape.IsNull())
4663     {
4664       aTexturedShape->SetToUpdate (AIS_Shaded);
4665       if (toSetImage)
4666       {
4667         if ((aTexturedIO->HasDisplayMode() && aTexturedIO->DisplayMode() != AIS_Shaded)
4668          || aCtx->DisplayMode() != AIS_Shaded)
4669         {
4670           aCtx->SetDisplayMode (aTexturedIO, AIS_Shaded, false);
4671         }
4672       }
4673     }
4674   }
4675   aCtx->Display (aTexturedIO, false);
4676   aTexturedIO->SynchronizeAspects();
4677   return 0;
4678 }
4679
4680 //! Auxiliary method to parse transformation persistence flags
4681 inline Standard_Boolean parseTrsfPersFlag (const TCollection_AsciiString& theFlagString,
4682                                            Graphic3d_TransModeFlags&      theFlags)
4683 {
4684   if (theFlagString == "zoom")
4685   {
4686     theFlags = Graphic3d_TMF_ZoomPers;
4687   }
4688   else if (theFlagString == "rotate")
4689   {
4690     theFlags = Graphic3d_TMF_RotatePers;
4691   }
4692   else if (theFlagString == "zoomrotate")
4693   {
4694     theFlags = Graphic3d_TMF_ZoomRotatePers;
4695   }
4696   else if (theFlagString == "trihedron"
4697         || theFlagString == "triedron")
4698   {
4699     theFlags = Graphic3d_TMF_TriedronPers;
4700   }
4701   else if (theFlagString == "none")
4702   {
4703     theFlags = Graphic3d_TMF_None;
4704   }
4705   else
4706   {
4707     return Standard_False;
4708   }
4709
4710   return Standard_True;
4711 }
4712
4713 //! Auxiliary method to parse transformation persistence flags
4714 inline Standard_Boolean parseTrsfPersCorner (const TCollection_AsciiString& theString,
4715                                              Aspect_TypeOfTriedronPosition& theCorner)
4716 {
4717   TCollection_AsciiString aString (theString);
4718   aString.LowerCase();
4719   if (aString == "center")
4720   {
4721     theCorner = Aspect_TOTP_CENTER;
4722   }
4723   else if (aString == "top"
4724         || aString == "upper")
4725   {
4726     theCorner = Aspect_TOTP_TOP;
4727   }
4728   else if (aString == "bottom"
4729         || aString == "lower")
4730   {
4731     theCorner = Aspect_TOTP_BOTTOM;
4732   }
4733   else if (aString == "left")
4734   {
4735     theCorner = Aspect_TOTP_LEFT;
4736   }
4737   else if (aString == "right")
4738   {
4739     theCorner = Aspect_TOTP_RIGHT;
4740   }
4741   else if (aString == "topleft"
4742         || aString == "leftupper"
4743         || aString == "upperleft")
4744   {
4745     theCorner = Aspect_TOTP_LEFT_UPPER;
4746   }
4747   else if (aString == "bottomleft"
4748         || aString == "leftlower"
4749         || aString == "lowerleft")
4750   {
4751     theCorner = Aspect_TOTP_LEFT_LOWER;
4752   }
4753   else if (aString == "topright"
4754         || aString == "rightupper"
4755         || aString == "upperright")
4756   {
4757     theCorner = Aspect_TOTP_RIGHT_UPPER;
4758   }
4759   else if (aString == "bottomright"
4760         || aString == "lowerright"
4761         || aString == "rightlower")
4762   {
4763     theCorner = Aspect_TOTP_RIGHT_LOWER;
4764   }
4765   else
4766   {
4767     return Standard_False;
4768   }
4769
4770   return Standard_True;
4771 }
4772
4773 //==============================================================================
4774 //function : VDisplay2
4775 //author   : ege
4776 //purpose  : Display an object from its name
4777 //==============================================================================
4778 static int VDisplay2 (Draw_Interpretor& theDI,
4779                       Standard_Integer  theArgNb,
4780                       const char**      theArgVec)
4781 {
4782   if (theArgNb < 2)
4783   {
4784     Message::SendFail ("Syntax error: wrong number of arguments.");
4785     return 1;
4786   }
4787   if (theArgNb == 2
4788    && TCollection_AsciiString (theArgVec[1]) == "*")
4789   {
4790     // alias
4791     return VDisplayAll (theDI, 1, theArgVec);
4792   }
4793
4794   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
4795   if (aCtx.IsNull())
4796   {
4797     ViewerTest::ViewerInit();
4798     aCtx = ViewerTest::GetAISContext();
4799   }
4800
4801   // Parse input arguments
4802   ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView());
4803   Standard_Integer   isMutable      = -1;
4804   Graphic3d_ZLayerId aZLayer        = Graphic3d_ZLayerId_UNKNOWN;
4805   Standard_Boolean   toReDisplay    = Standard_False;
4806   Standard_Integer   isSelectable   = -1;
4807   Standard_Integer   anObjDispMode  = -2;
4808   Standard_Integer   anObjHighMode  = -2;
4809   Standard_Boolean   toSetTrsfPers  = Standard_False;
4810   Handle(Graphic3d_TransformPers) aTrsfPers;
4811   TColStd_SequenceOfAsciiString aNamesOfDisplayIO;
4812   AIS_DisplayStatus aDispStatus = AIS_DS_None;
4813   Standard_Integer toDisplayInView = Standard_False;
4814   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4815   {
4816     const TCollection_AsciiString aName     = theArgVec[anArgIter];
4817     TCollection_AsciiString       aNameCase = aName;
4818     aNameCase.LowerCase();
4819     if (anUpdateTool.parseRedrawMode (aName))
4820     {
4821       continue;
4822     }
4823     else if (aNameCase == "-mutable")
4824     {
4825       isMutable = 1;
4826     }
4827     else if (aNameCase == "-neutral")
4828     {
4829       aDispStatus = AIS_DS_Displayed;
4830     }
4831     else if (aNameCase == "-immediate"
4832           || aNameCase == "-top")
4833     {
4834       aZLayer = Graphic3d_ZLayerId_Top;
4835     }
4836     else if (aNameCase == "-topmost")
4837     {
4838       aZLayer = Graphic3d_ZLayerId_Topmost;
4839     }
4840     else if (aNameCase == "-osd"
4841           || aNameCase == "-toposd"
4842           || aNameCase == "-overlay")
4843     {
4844       aZLayer = Graphic3d_ZLayerId_TopOSD;
4845     }
4846     else if (aNameCase == "-botosd"
4847           || aNameCase == "-underlay")
4848     {
4849       aZLayer = Graphic3d_ZLayerId_BotOSD;
4850     }
4851     else if (aNameCase == "-select"
4852           || aNameCase == "-selectable")
4853     {
4854       isSelectable = 1;
4855     }
4856     else if (aNameCase == "-noselect"
4857           || aNameCase == "-noselection")
4858     {
4859       isSelectable = 0;
4860     }
4861     else if (aNameCase == "-dispmode"
4862           || aNameCase == "-displaymode")
4863     {
4864       if (++anArgIter >= theArgNb)
4865       {
4866         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4867         return 1;
4868       }
4869
4870       anObjDispMode = Draw::Atoi (theArgVec [anArgIter]);
4871     }
4872     else if (aNameCase == "-himode"
4873           || aNameCase == "-highmode"
4874           || aNameCase == "-highlightmode")
4875     {
4876       if (++anArgIter >= theArgNb)
4877       {
4878         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4879         return 1;
4880       }
4881
4882       anObjHighMode = Draw::Atoi (theArgVec [anArgIter]);
4883     }
4884     else if (aNameCase == "-3d")
4885     {
4886       toSetTrsfPers  = Standard_True;
4887       aTrsfPers.Nullify();
4888     }
4889     else if (aNameCase == "-2d"
4890           || aNameCase == "-trihedron"
4891           || aNameCase == "-triedron")
4892     {
4893       toSetTrsfPers  = Standard_True;
4894       aTrsfPers = new Graphic3d_TransformPers (aNameCase == "-2d" ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4895
4896       if (anArgIter + 1 < theArgNb)
4897       {
4898         Aspect_TypeOfTriedronPosition aCorner = Aspect_TOTP_CENTER;
4899         if (parseTrsfPersCorner (theArgVec[anArgIter + 1], aCorner))
4900         {
4901           ++anArgIter;
4902           aTrsfPers->SetCorner2d (aCorner);
4903
4904           if (anArgIter + 2 < theArgNb)
4905           {
4906             TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
4907             TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
4908             if (anX.IsIntegerValue()
4909              && anY.IsIntegerValue())
4910             {
4911               anArgIter += 2;
4912               aTrsfPers->SetOffset2d (Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue()));
4913             }
4914           }
4915         }
4916       }
4917     }
4918     else if (aNameCase == "-trsfpers"
4919           || aNameCase == "-pers")
4920     {
4921       if (++anArgIter >= theArgNb
4922        || !aTrsfPers.IsNull())
4923       {
4924         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4925         return 1;
4926       }
4927
4928       toSetTrsfPers  = Standard_True;
4929       Graphic3d_TransModeFlags aTrsfPersFlags = Graphic3d_TMF_None;
4930       TCollection_AsciiString aPersFlags (theArgVec [anArgIter]);
4931       aPersFlags.LowerCase();
4932       if (!parseTrsfPersFlag (aPersFlags, aTrsfPersFlags))
4933       {
4934         Message::SendFail() << "Error: wrong transform persistence flags " << theArgVec [anArgIter] << ".";
4935         return 1;
4936       }
4937
4938       if (aTrsfPersFlags == Graphic3d_TMF_TriedronPers)
4939       {
4940         aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER);
4941       }
4942       else if (aTrsfPersFlags != Graphic3d_TMF_None)
4943       {
4944         aTrsfPers = new Graphic3d_TransformPers (aTrsfPersFlags, gp_Pnt());
4945       }
4946     }
4947     else if (aNameCase == "-trsfperspos"
4948           || aNameCase == "-perspos")
4949     {
4950       if (anArgIter + 2 >= theArgNb
4951        || aTrsfPers.IsNull())
4952       {
4953         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4954         return 1;
4955       }
4956
4957       TCollection_AsciiString aX (theArgVec[++anArgIter]);
4958       TCollection_AsciiString aY (theArgVec[++anArgIter]);
4959       TCollection_AsciiString aZ = "0";
4960       if (!aX.IsRealValue()
4961        || !aY.IsRealValue())
4962       {
4963         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4964         return 1;
4965       }
4966       if (anArgIter + 1 < theArgNb)
4967       {
4968         TCollection_AsciiString aTemp = theArgVec[anArgIter + 1];
4969         if (aTemp.IsRealValue())
4970         {
4971           aZ = aTemp;
4972           ++anArgIter;
4973         }
4974       }
4975
4976       const gp_Pnt aPnt (aX.RealValue(), aY.RealValue(), aZ.RealValue());
4977       if (aTrsfPers->IsZoomOrRotate())
4978       {
4979         aTrsfPers->SetAnchorPoint (aPnt);
4980       }
4981       else if (aTrsfPers->IsTrihedronOr2d())
4982       {
4983         aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (aTrsfPers->Mode(), aPnt);
4984       }
4985     }
4986     else if (aNameCase == "-layer"
4987           || aNameCase == "-zlayer")
4988     {
4989       ++anArgIter;
4990       if (anArgIter >= theArgNb
4991       || !ViewerTest::ParseZLayer (theArgVec[anArgIter], aZLayer)
4992       ||  aZLayer == Graphic3d_ZLayerId_UNKNOWN)
4993       {
4994         Message::SendFail() << "Error: wrong syntax at " << aName << ".";
4995         return 1;
4996       }
4997     }
4998     else if (aNameCase == "-view"
4999           || aNameCase == "-inview")
5000     {
5001       toDisplayInView = Standard_True;
5002     }
5003     else if (aNameCase == "-redisplay")
5004     {
5005       toReDisplay = Standard_True;
5006     }
5007     else if (aNameCase == "-erased"
5008           || aNameCase == "-load")
5009     {
5010       aDispStatus = AIS_DS_Erased;
5011     }
5012     else
5013     {
5014       aNamesOfDisplayIO.Append (aName);
5015     }
5016   }
5017
5018   if (aNamesOfDisplayIO.IsEmpty())
5019   {
5020     Message::SendFail ("Syntax error: wrong number of arguments.");
5021     return 1;
5022   }
5023
5024   // Display interactive objects
5025   for (Standard_Integer anIter = 1; anIter <= aNamesOfDisplayIO.Length(); ++anIter)
5026   {
5027     const TCollection_AsciiString& aName = aNamesOfDisplayIO.Value (anIter);
5028     Handle(AIS_InteractiveObject) aShape;
5029     if (!GetMapOfAIS().Find2 (aName, aShape))
5030     {
5031       // create the AIS_Shape from a name
5032       TopoDS_Shape aDrawShape = DBRep::GetExisting (aName);
5033       if (!aDrawShape.IsNull())
5034       {
5035         aShape = new AIS_Shape (aDrawShape);
5036         if (isMutable != -1)
5037         {
5038           aShape->SetMutable (isMutable == 1);
5039         }
5040         if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
5041         {
5042           aShape->SetZLayer (aZLayer);
5043         }
5044         if (toSetTrsfPers)
5045         {
5046           aCtx->SetTransformPersistence (aShape, aTrsfPers);
5047         }
5048         if (anObjDispMode != -2)
5049         {
5050           if (anObjDispMode == -1)
5051           {
5052             aShape->UnsetDisplayMode();
5053           }
5054           if (!aShape->AcceptDisplayMode (anObjDispMode))
5055           {
5056             Message::SendFail() << "Syntax error: " << aShape->DynamicType()->Name() << " rejects " << anObjDispMode << " display mode";
5057             return 1;
5058           }
5059           else
5060           {
5061             aShape->SetDisplayMode (anObjDispMode);
5062           }
5063         }
5064         if (anObjHighMode != -2)
5065         {
5066           if (anObjHighMode != -1
5067           && !aShape->AcceptDisplayMode (anObjHighMode))
5068           {
5069             Message::SendFail() << "Syntax error: " << aShape->DynamicType()->Name() << " rejects " << anObjHighMode << " display mode";
5070             return 1;
5071           }
5072           aShape->SetHilightMode (anObjHighMode);
5073         }
5074
5075         GetMapOfAIS().Bind (aShape, aName);
5076         Standard_Integer aDispMode = aShape->HasDisplayMode()
5077                                    ? aShape->DisplayMode()
5078                                    : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
5079                                     ? aCtx->DisplayMode()
5080                                     : 0);
5081         Standard_Integer aSelMode = -1;
5082         if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
5083         {
5084           aSelMode = aShape->GlobalSelectionMode();
5085         }
5086
5087         aCtx->Display (aShape, aDispMode, aSelMode, Standard_False, aDispStatus);
5088         if (toDisplayInView)
5089         {
5090           for (V3d_ListOfViewIterator aViewIter (aCtx->CurrentViewer()->DefinedViewIterator()); aViewIter.More(); aViewIter.Next())
5091           {
5092             aCtx->SetViewAffinity (aShape, aViewIter.Value(), Standard_False);
5093           }
5094           aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
5095         }
5096       }
5097       else
5098       {
5099         Message::SendFail() << "Error: object with name '" << aName << "' does not exist!";
5100       }
5101       continue;
5102     }
5103
5104     if (isMutable != -1)
5105     {
5106       aShape->SetMutable (isMutable == 1);
5107     }
5108     if (aZLayer != Graphic3d_ZLayerId_UNKNOWN)
5109     {
5110       aShape->SetZLayer (aZLayer);
5111     }
5112     if (toSetTrsfPers)
5113     {
5114       aCtx->SetTransformPersistence (aShape, aTrsfPers);
5115     }
5116     if (anObjDispMode != -2)
5117     {
5118       aShape->SetDisplayMode (anObjDispMode);
5119     }
5120     if (anObjHighMode != -2)
5121     {
5122       aShape->SetHilightMode (anObjHighMode);
5123     }
5124     Standard_Integer aDispMode = aShape->HasDisplayMode()
5125                                 ? aShape->DisplayMode()
5126                                 : (aShape->AcceptDisplayMode (aCtx->DisplayMode())
5127                                 ? aCtx->DisplayMode()
5128                                 : 0);
5129     Standard_Integer aSelMode = -1;
5130     if (isSelectable ==  1 || (isSelectable == -1 && aCtx->GetAutoActivateSelection()))
5131     {
5132       aSelMode = aShape->GlobalSelectionMode();
5133     }
5134
5135     if (aShape->Type() == AIS_KOI_Datum)
5136     {
5137       aCtx->Display (aShape, Standard_False);
5138     }
5139     else
5140     {
5141       theDI << "Display " << aName << "\n";
5142
5143       // update the Shape in the AIS_Shape
5144       TopoDS_Shape      aNewShape = DBRep::GetExisting (aName);
5145       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aShape);
5146       if (!aShapePrs.IsNull())
5147       {
5148         if (!aShapePrs->Shape().IsEqual (aNewShape))
5149         {
5150           toReDisplay = Standard_True;
5151         }
5152         aShapePrs->Set (aNewShape);
5153       }
5154       if (toReDisplay)
5155       {
5156         aCtx->Redisplay (aShape, Standard_False);
5157       }
5158
5159       if (aSelMode == -1)
5160       {
5161         aCtx->Erase (aShape, Standard_False);
5162       }
5163       aCtx->Display (aShape, aDispMode, aSelMode, Standard_False, aDispStatus);
5164       if (toDisplayInView)
5165       {
5166         aCtx->SetViewAffinity (aShape, ViewerTest::CurrentView(), Standard_True);
5167       }
5168     }
5169   }
5170
5171   return 0;
5172 }
5173
5174 //=======================================================================
5175 //function : VNbDisplayed
5176 //purpose  : Returns number of displayed objects
5177 //=======================================================================
5178 static Standard_Integer VNbDisplayed (Draw_Interpretor& theDi,
5179                                       Standard_Integer theArgsNb,
5180                                       const char** theArgVec)
5181 {
5182   if(theArgsNb != 1)
5183   {
5184     theDi << "Usage : " << theArgVec[0] << "\n";
5185     return 1;
5186   }
5187
5188   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5189   if (aContextAIS.IsNull())
5190   {
5191     Message::SendFail ("Syntax error: AIS context is not available.");
5192     return 1;
5193   }
5194
5195   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5196   if(aContext.IsNull())
5197   {
5198     theDi << "use 'vinit' command before " << theArgVec[0] << "\n";
5199     return 1;
5200   }
5201
5202   AIS_ListOfInteractive aListOfIO;
5203   aContextAIS->DisplayedObjects (aListOfIO);
5204
5205   theDi << aListOfIO.Extent() << "\n";
5206   return 0;
5207 }
5208
5209 //===============================================================================================
5210 //function : VUpdate
5211 //purpose  :
5212 //===============================================================================================
5213 static int VUpdate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
5214 {
5215   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5216   if (aContextAIS.IsNull())
5217   {
5218     Message::SendFail ("Syntax error: AIS context is not available.");
5219     return 1;
5220   }
5221
5222   if (theArgsNb < 2)
5223   {
5224     Message::SendFail ("Syntax error: insufficient arguments. Type help for more information.");
5225     return 1;
5226   }
5227
5228   AIS_ListOfInteractive aListOfIO;
5229   for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
5230   {
5231     TCollection_AsciiString aName = TCollection_AsciiString (theArgVec[anArgIt]);
5232
5233     Handle(AIS_InteractiveObject) anAISObj;
5234     GetMapOfAIS().Find2 (aName, anAISObj);
5235     if (anAISObj.IsNull())
5236     {
5237       Message::SendFail() << theArgVec[0] << ": no AIS interactive object named \"" << aName << "\".";
5238       return 1;
5239     }
5240
5241     aListOfIO.Append (anAISObj);
5242   }
5243
5244   AIS_ListIteratorOfListOfInteractive anIOIt (aListOfIO);
5245   for (; anIOIt.More(); anIOIt.Next())
5246   {
5247     aContextAIS->Update (anIOIt.Value(), Standard_False);
5248   }
5249
5250   aContextAIS->UpdateCurrentViewer();
5251
5252   return 0;
5253 }
5254
5255 //==============================================================================
5256 //function : VShading
5257 //purpose  : Sharpen or roughten the quality of the shading
5258 //Draw arg : vshading ShapeName 0.1->0.00001  1 deg-> 30 deg
5259 //==============================================================================
5260 static int VShading(Draw_Interpretor& ,Standard_Integer argc, const char** argv)
5261 {
5262   Standard_Real    myDevCoef;
5263   Handle(AIS_InteractiveObject) TheAisIO;
5264
5265   // Verifications
5266   const Standard_Boolean HaveToSet = (strcasecmp(argv[0],"vsetshading") == 0);
5267   if (argc < 3) {
5268     myDevCoef  = 0.0008;
5269   } else {
5270     myDevCoef  =Draw::Atof(argv[2]);
5271   }
5272
5273   TCollection_AsciiString name=argv[1];
5274   GetMapOfAIS().Find2(name, TheAisIO);
5275   if (TheAisIO.IsNull())
5276   {
5277     TopoDS_Shape aDrawShape = DBRep::GetExisting (name);
5278     if (!aDrawShape.IsNull())
5279     {
5280       TheAisIO = new AIS_Shape (aDrawShape);
5281     }
5282   }
5283
5284   if (HaveToSet)
5285     TheAISContext()->SetDeviationCoefficient(TheAisIO,myDevCoef,Standard_True);
5286   else
5287     TheAISContext()->SetDeviationCoefficient(TheAisIO,0.0008,Standard_True);
5288
5289   TheAISContext()->Redisplay (TheAisIO, Standard_True);
5290   return 0;
5291 }
5292
5293 //! Auxiliary method to print Interactive Object information
5294 static void objInfo (const NCollection_Map<Handle(AIS_InteractiveObject)>& theDetected,
5295                      const Handle(AIS_InteractiveObject)&                  theObj,
5296                      Draw_Interpretor&                                     theDI)
5297 {
5298   if (theObj.IsNull())
5299   {
5300     theDI << "NULL presentation\n";
5301     return;
5302   }
5303
5304   theDI << (TheAISContext()->IsDisplayed (theObj) ? "Displayed"  : "Hidden   ")
5305         << (TheAISContext()->IsSelected  (theObj) ? " Selected" : "         ")
5306         << (theDetected.Contains (theObj)         ? " Detected" : "         ")
5307         << " Type: ";
5308   if (theObj->Type() == AIS_KOI_Datum)
5309   {
5310     // AIS_Datum
5311     if      (theObj->Signature() == 3) { theDI << " AIS_Trihedron"; }
5312     else if (theObj->Signature() == 2) { theDI << " AIS_Axis"; }
5313     else if (theObj->Signature() == 6) { theDI << " AIS_Circle"; }
5314     else if (theObj->Signature() == 5) { theDI << " AIS_Line"; }
5315     else if (theObj->Signature() == 7) { theDI << " AIS_Plane"; }
5316     else if (theObj->Signature() == 1) { theDI << " AIS_Point"; }
5317     else if (theObj->Signature() == 4) { theDI << " AIS_PlaneTrihedron"; }
5318   }
5319   // AIS_Shape
5320   else if (theObj->Type()      == AIS_KOI_Shape
5321         && theObj->Signature() == 0)
5322   {
5323     theDI << " AIS_Shape";
5324   }
5325   else if (theObj->Type() == AIS_KOI_Relation)
5326   {
5327     // PrsDim_Dimention and AIS_Relation
5328     Handle(PrsDim_Relation) aRelation = Handle(PrsDim_Relation)::DownCast (theObj);
5329     switch (aRelation->KindOfDimension())
5330     {
5331       case PrsDim_KOD_PLANEANGLE:     theDI << " PrsDim_AngleDimension"; break;
5332       case PrsDim_KOD_LENGTH:         theDI << " PrsDim_Chamf2/3dDimension/PrsDim_LengthDimension"; break;
5333       case PrsDim_KOD_DIAMETER:       theDI << " PrsDim_DiameterDimension"; break;
5334       case PrsDim_KOD_ELLIPSERADIUS:  theDI << " PrsDim_EllipseRadiusDimension"; break;
5335       //case PrsDim_KOD_FILLETRADIUS:   theDI << " PrsDim_FilletRadiusDimension "; break;
5336       case PrsDim_KOD_OFFSET:         theDI << " PrsDim_OffsetDimension"; break;
5337       case PrsDim_KOD_RADIUS:         theDI << " PrsDim_RadiusDimension"; break;
5338       default:                     theDI << " UNKNOWN dimension"; break;
5339     }
5340   }
5341   else
5342   {
5343     theDI << " UserPrs";
5344   }
5345   theDI << " (" << theObj->DynamicType()->Name() << ")";
5346 }
5347
5348 //! Print information about locally selected sub-shapes
5349 template <typename T>
5350 static void printLocalSelectionInfo (const T& theContext, Draw_Interpretor& theDI)
5351 {
5352   const Standard_Boolean isGlobalCtx = (theContext->DynamicType() == STANDARD_TYPE(AIS_InteractiveContext));
5353   TCollection_AsciiString aPrevName;
5354   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
5355   {
5356     const Handle(AIS_Shape) aShapeIO = Handle(AIS_Shape)::DownCast (theContext->SelectedInteractive());
5357     const Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
5358     if (aShapeIO.IsNull() || anOwner.IsNull())
5359       continue;
5360     if (isGlobalCtx)
5361     {
5362       if (anOwner == aShapeIO->GlobalSelOwner())
5363         continue;
5364     }
5365     const TopoDS_Shape      aSubShape = theContext->SelectedShape();
5366     if (aSubShape.IsNull()
5367       || aShapeIO.IsNull()
5368       || !GetMapOfAIS().IsBound1 (aShapeIO))
5369     {
5370       continue;
5371     }
5372
5373     const TCollection_AsciiString aParentName = GetMapOfAIS().Find1 (aShapeIO);
5374     TopTools_MapOfShape aFilter;
5375     Standard_Integer    aNumber = 0;
5376     const TopoDS_Shape  aShape  = aShapeIO->Shape();
5377     for (TopExp_Explorer anIter (aShape, aSubShape.ShapeType());
5378          anIter.More(); anIter.Next())
5379     {
5380       if (!aFilter.Add (anIter.Current()))
5381       {
5382         continue; // filter duplicates
5383       }
5384
5385       ++aNumber;
5386       if (!anIter.Current().IsSame (aSubShape))
5387       {
5388         continue;
5389       }
5390
5391       Standard_CString aShapeName = NULL;
5392       switch (aSubShape.ShapeType())
5393       {
5394         case TopAbs_COMPOUND:  aShapeName = " Compound"; break;
5395         case TopAbs_COMPSOLID: aShapeName = "CompSolid"; break;
5396         case TopAbs_SOLID:     aShapeName = "    Solid"; break;
5397         case TopAbs_SHELL:     aShapeName = "    Shell"; break;
5398         case TopAbs_FACE:      aShapeName = "     Face"; break;
5399         case TopAbs_WIRE:      aShapeName = "     Wire"; break;
5400         case TopAbs_EDGE:      aShapeName = "     Edge"; break;
5401         case TopAbs_VERTEX:    aShapeName = "   Vertex"; break;
5402         default:
5403         case TopAbs_SHAPE:     aShapeName = "    Shape"; break;
5404       }
5405
5406       if (aParentName != aPrevName)
5407       {
5408         theDI << "Locally selected sub-shapes within " << aParentName << ":\n";
5409         aPrevName = aParentName;
5410       }
5411       theDI << "  " << aShapeName << " #" << aNumber << "\n";
5412       break;
5413     }
5414   }
5415 }
5416
5417 //==============================================================================
5418 //function : VState
5419 //purpose  :
5420 //==============================================================================
5421 static Standard_Integer VState (Draw_Interpretor& theDI,
5422                                 Standard_Integer  theArgNb,
5423                                 Standard_CString* theArgVec)
5424 {
5425   Handle(AIS_InteractiveContext) aCtx = TheAISContext();
5426   if (aCtx.IsNull())
5427   {
5428     Message::SendFail ("Error: No opened viewer!");
5429     return 1;
5430   }
5431
5432   Standard_Boolean toPrintEntities = Standard_False;
5433   Standard_Boolean toCheckSelected = Standard_False;
5434
5435   for (Standard_Integer anArgIdx = 1; anArgIdx < theArgNb; ++anArgIdx)
5436   {
5437     TCollection_AsciiString anOption (theArgVec[anArgIdx]);
5438     anOption.LowerCase();
5439     if (anOption == "-detectedentities"
5440       || anOption == "-entities")
5441     {
5442       toPrintEntities = Standard_True;
5443     }
5444     else if (anOption == "-hasselected")
5445     {
5446       toCheckSelected = Standard_True;
5447     }
5448   }
5449
5450   if (toCheckSelected)
5451   {
5452     aCtx->InitSelected();
5453     TCollection_AsciiString hasSelected (static_cast<Standard_Integer> (aCtx->HasSelectedShape()));
5454     theDI << "Check if context has selected shape: " << hasSelected << "\n";
5455
5456     return 0;
5457   }
5458
5459   if (toPrintEntities)
5460   {
5461     theDI << "Detected entities:\n";
5462     Handle(StdSelect_ViewerSelector3d) aSelector = aCtx->MainSelector();
5463
5464     SelectMgr_SelectingVolumeManager aMgr = aSelector->GetManager();
5465     for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
5466     {
5467       const SelectMgr_SortCriterion&         aPickData = aSelector->PickedData (aPickIter);
5468       const Handle(Select3D_SensitiveEntity)& anEntity = aSelector->PickedEntity (aPickIter);
5469       const Handle(SelectMgr_EntityOwner)& anOwner = anEntity->OwnerId();
5470       Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
5471
5472       TCollection_AsciiString aName;
5473       GetMapOfAIS().Find1 (anObj, aName);
5474       aName.LeftJustify (20, ' ');
5475       char anInfoStr[512];
5476       if (aPickData.Normal.SquareModulus() > ShortRealEpsilon())
5477       {
5478         Sprintf (anInfoStr,
5479                  " Depth: %g Distance: %g Point: %g %g %g Normal: %g %g %g",
5480                  aPickData.Depth,
5481                  aPickData.MinDist,
5482                  aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z(),
5483                  aPickData.Normal.x(), aPickData.Normal.y(), aPickData.Normal.z());
5484       }
5485       else
5486       {
5487         Sprintf (anInfoStr,
5488                  " Depth: %g Distance: %g Point: %g %g %g",
5489                  aPickData.Depth,
5490                  aPickData.MinDist,
5491                  aPickData.Point.X(), aPickData.Point.Y(), aPickData.Point.Z());
5492       }
5493       theDI << "  " << aName
5494             << anInfoStr
5495             << " (" << anEntity->DynamicType()->Name() << ")"
5496             << "\n";
5497
5498       Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
5499       if (!aBRepOwner.IsNull())
5500       {
5501         theDI << "                       Detected Shape: "
5502               << aBRepOwner->Shape().TShape()->DynamicType()->Name()
5503               << "\n";
5504       }
5505
5506       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast (anEntity);
5507       if (!aWire.IsNull())
5508       {
5509         Handle(Select3D_SensitiveEntity) aSen = aWire->GetLastDetected();
5510         theDI << "                       Detected Child: "
5511               << aSen->DynamicType()->Name()
5512               << "\n";
5513       }
5514
5515       Handle(Select3D_SensitivePrimitiveArray) aPrimArr = Handle(Select3D_SensitivePrimitiveArray)::DownCast (anEntity);
5516       if (!aPrimArr.IsNull())
5517       {
5518         theDI << "                       Detected Element: "
5519               << aPrimArr->LastDetectedElement()
5520               << "\n";
5521       }
5522     }
5523     return 0;
5524   }
5525
5526   NCollection_Map<Handle(AIS_InteractiveObject)> aDetected;
5527   for (aCtx->InitDetected(); aCtx->MoreDetected(); aCtx->NextDetected())
5528   {
5529     aDetected.Add (Handle(AIS_InteractiveObject)::DownCast (aCtx->DetectedCurrentOwner()->Selectable()));
5530   }
5531
5532   const Standard_Boolean toShowAll = (theArgNb >= 2 && *theArgVec[1] == '*');
5533   if (theArgNb >= 2
5534    && !toShowAll)
5535   {
5536     for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5537     {
5538       const TCollection_AsciiString anObjName = theArgVec[anArgIter];
5539       Handle(AIS_InteractiveObject) anObj;
5540       if (!GetMapOfAIS().Find2 (anObjName, anObj))
5541       {
5542         theDI << anObjName << " doesn't exist!\n";
5543         continue;
5544       }
5545
5546       TCollection_AsciiString aName = anObjName;
5547       aName.LeftJustify (20, ' ');
5548       theDI << "  " << aName << " ";
5549       objInfo (aDetected, anObj, theDI);
5550       theDI << "\n";
5551     }
5552     return 0;
5553   }
5554
5555   if (aCtx->NbSelected() > 0 && !toShowAll)
5556   {
5557     NCollection_DataMap<Handle(SelectMgr_EntityOwner), TopoDS_Shape> anOwnerShapeMap;
5558     for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected())
5559     {
5560       const Handle(SelectMgr_EntityOwner) anOwner = aCtx->SelectedOwner();
5561       const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
5562       // handle whole object selection
5563       if (anOwner == anObj->GlobalSelOwner())
5564       {
5565         TCollection_AsciiString aName;
5566         GetMapOfAIS().Find1 (anObj, aName);
5567         aName.LeftJustify (20, ' ');
5568         theDI << aName << " ";
5569         objInfo (aDetected, anObj, theDI);
5570         theDI << "\n";
5571       }
5572     }
5573
5574     // process selected sub-shapes
5575     printLocalSelectionInfo (aCtx, theDI);
5576
5577     return 0;
5578   }
5579
5580   theDI << "Neutral-point state:\n";
5581   for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5582        anObjIter.More(); anObjIter.Next())
5583   {
5584     if (anObjIter.Key1().IsNull())
5585     {
5586       continue;
5587     }
5588
5589     TCollection_AsciiString aName = anObjIter.Key2();
5590     aName.LeftJustify (20, ' ');
5591     theDI << "  " << aName << " ";
5592     objInfo (aDetected, anObjIter.Key1(), theDI);
5593     theDI << "\n";
5594   }
5595   printLocalSelectionInfo (aCtx, theDI);
5596   return 0;
5597 }
5598
5599 //=======================================================================
5600 //function : PickShape
5601 //purpose  : First Activate the rightmode + Put Filters to be able to
5602 //           pick objets that are of type <TheType>...
5603 //=======================================================================
5604
5605 TopoDS_Shape ViewerTest::PickShape (const TopAbs_ShapeEnum theShapeType,
5606                                     const Standard_Integer theMaxPick)
5607 {
5608   Handle(TopTools_HArray1OfShape) aResArray = new TopTools_HArray1OfShape (1, 1);
5609   PickShapes (theShapeType, aResArray, theMaxPick);
5610   return aResArray->First();
5611 }
5612
5613 //=======================================================================
5614 //function : PickShapes
5615 //purpose  :
5616 //=======================================================================
5617 Standard_Boolean ViewerTest::PickShapes (const TopAbs_ShapeEnum theShapeType,
5618                                          Handle(TopTools_HArray1OfShape)& theResArray,
5619                                          const Standard_Integer theMaxPick)
5620 {
5621   const Standard_Integer aNbToReach = theResArray->Length();
5622   if (aNbToReach > 1)
5623   {
5624     Message::SendWarning ("WARNING : Pick with Shift+ MB1 for Selection of more than 1 object");
5625   }
5626
5627   // step 1: prepare the data
5628   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
5629   aCtx->RemoveFilters();
5630   AIS_ListOfInteractive aDispObjects;
5631   aCtx->DisplayedObjects (aDispObjects);
5632   if (theShapeType == TopAbs_SHAPE)
5633   {
5634     aCtx->AddFilter (new AIS_TypeFilter (AIS_KOI_Shape));
5635   }
5636   else
5637   {
5638     aCtx->AddFilter (new StdSelect_ShapeTypeFilter (theShapeType));
5639   }
5640
5641   const Standard_Integer aSelMode = AIS_Shape::SelectionMode (theShapeType);
5642   for (AIS_ListOfInteractive::Iterator anObjIter (aDispObjects); anObjIter.More(); anObjIter.Next())
5643   {
5644     if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (anObjIter.Value()))
5645     {
5646       aCtx->SetSelectionModeActive (aShapePrs, aSelMode, true, AIS_SelectionModesConcurrency_Single);
5647     }
5648   }
5649
5650   // step 2 : wait for the selection...
5651   Standard_Integer aNbPickGood = 0, aNbPickFail = 0;
5652   Standard_Integer argccc = 5;
5653   const char *bufff[] = { "A", "B", "C", "D", "E" };
5654   const char **argvvv = (const char** )bufff;
5655   for (; aNbPickGood < aNbToReach && aNbPickFail <= theMaxPick; )
5656   {
5657     while (ViewerMainLoop (argccc, argvvv)) {}
5658     Standard_Integer aNbStored = aCtx->NbSelected();
5659     if (aNbStored != aNbPickGood)
5660     {
5661       aNbPickGood = aNbStored;
5662     }
5663     else
5664     {
5665       ++aNbPickFail;
5666     }
5667     Message::SendInfo() << "NbPicked =  " << aNbPickGood << " |  Nb Pick Fail :" << aNbPickFail;
5668   }
5669
5670   // step3 get result.
5671   if (aNbPickFail >= aNbToReach)
5672   {
5673     return Standard_False;
5674   }
5675
5676   Standard_Integer anIndex = theResArray->Lower();
5677   for (aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected(), ++anIndex)
5678   {
5679     if (aCtx->HasSelectedShape())
5680     {
5681       theResArray->SetValue (anIndex, aCtx->SelectedShape());
5682     }
5683     else
5684     {
5685       Handle(AIS_InteractiveObject) IO = aCtx->SelectedInteractive();
5686       theResArray->SetValue (anIndex, Handle(AIS_Shape)::DownCast (IO)->Shape());
5687     }
5688   }
5689
5690   aCtx->RemoveFilters();
5691   if (theShapeType != TopAbs_SHAPE)
5692   {
5693     for (AIS_ListOfInteractive::Iterator anObjIter (aDispObjects); anObjIter.More(); anObjIter.Next())
5694     {
5695       if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (anObjIter.Value()))
5696       {
5697         aCtx->SetSelectionModeActive (aShapePrs, aSelMode, true, AIS_SelectionModesConcurrency_Single);
5698       }
5699     }
5700   }
5701   return Standard_True;
5702 }
5703
5704 //=======================================================================
5705 //function : VPickShape
5706 //purpose  :
5707 //=======================================================================
5708 static int VPickShape( Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5709 {
5710   TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
5711   if (argc != 1)
5712   {
5713     TCollection_AsciiString aShapeArg (argv[1]);
5714     aShapeArg.LowerCase();
5715     aShapeType = TopAbs_COMPOUND;
5716     if      (aShapeArg == "v"
5717           || aShapeArg == "vertex") aShapeType = TopAbs_VERTEX;
5718     else if (aShapeArg == "e"
5719           || aShapeArg == "edge")   aShapeType = TopAbs_EDGE;
5720     else if (aShapeArg == "w"
5721           || aShapeArg == "wire")   aShapeType = TopAbs_WIRE;
5722     else if (aShapeArg == "f"
5723           || aShapeArg == "face")   aShapeType = TopAbs_FACE;
5724     else if (aShapeArg == "shape")  aShapeType = TopAbs_SHAPE;
5725     else if (aShapeArg == "shell")  aShapeType = TopAbs_SHELL;
5726     else if (aShapeArg == "solid")  aShapeType = TopAbs_SOLID;
5727     else
5728     {
5729       Message::SendFail() << "Syntax error at '" << argv[1] << "'";
5730       return 1;
5731     }
5732   }
5733
5734   static Standard_Integer THE_NB_SHAPES_OF_TYPE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
5735   static const TCollection_AsciiString THE_NAME_TYPE[8] = {"COMPS","SOL","SHE","F","W","E","V","SHAP"};
5736
5737   const Standard_Integer aNbToPick = argc > 2 ? argc - 2 : 1;
5738   if (aNbToPick == 1)
5739   {
5740     TopoDS_Shape aPickedShape = ViewerTest::PickShape (aShapeType);
5741     if (aPickedShape.IsNull())
5742     {
5743       return 1;
5744     }
5745
5746     TCollection_AsciiString aName;
5747     if (argc > 2)
5748     {
5749       aName = argv[2];
5750     }
5751     else
5752     {
5753       const int aShapeIndex = ++THE_NB_SHAPES_OF_TYPE[Standard_Integer(aShapeType)];
5754       aName = TCollection_AsciiString ("Picked_") + THE_NAME_TYPE[Standard_Integer(aShapeType)] + "_" + aShapeIndex;
5755     }
5756
5757     DBRep::Set (aName.ToCString(), aPickedShape);
5758     Handle(AIS_Shape) aShapePrs = new AIS_Shape (aPickedShape);
5759     ViewerTest::Display (aName, aShapePrs, false, true);
5760     di << "Name of picked shape: " << aName <<"\n";
5761   }
5762   else
5763   {
5764     TCollection_AsciiString aName (argv[2]);
5765     aName.LowerCase();
5766     const Standard_Boolean isAutoNaming = aName == ".";
5767     Handle(TopTools_HArray1OfShape) aPickedArray = new TopTools_HArray1OfShape (1, aNbToPick);
5768     if (ViewerTest::PickShapes (aShapeType, aPickedArray))
5769     {
5770       for (Standard_Integer aPickedIter = aPickedArray->Lower(); aPickedIter <= aPickedArray->Upper(); ++aPickedIter)
5771       {
5772         TopoDS_Shape aPickedShape = aPickedArray->Value (aPickedIter);
5773         aName.Clear();
5774         if (!aPickedShape.IsNull()
5775          && isAutoNaming)
5776         {
5777           const int aShapeIndex = ++THE_NB_SHAPES_OF_TYPE[Standard_Integer(aShapeType)];
5778           aName = TCollection_AsciiString ("Picked_") + THE_NAME_TYPE[Standard_Integer(aShapeType)] + "_" + aShapeIndex;
5779         }
5780         else
5781         {
5782           aName = argv[1 + aPickedIter];
5783         }
5784
5785         DBRep::Set (aName.ToCString(), aPickedShape);
5786         Handle(AIS_Shape) aShapePrs = new AIS_Shape (aPickedShape);
5787         di << "Display of picked shape #" << aPickedIter << " - name: " << aName <<"\n";
5788         ViewerTest::Display (aName, aShapePrs, false, true);
5789       }
5790     }
5791   }
5792   TheAISContext()->UpdateCurrentViewer();
5793   return 0;
5794 }
5795
5796 //=======================================================================
5797 //function : VSelFilter
5798 //purpose  :
5799 //=======================================================================
5800 static int VSelFilter(Draw_Interpretor& , Standard_Integer theArgc,
5801                       const char** theArgv)
5802 {
5803   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5804   if (aContext.IsNull())
5805   {
5806     Message::SendFail ("Error: AIS context is not available.");
5807     return 1;
5808   }
5809
5810   for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
5811   {
5812     TCollection_AsciiString anArg (theArgv[anArgIter]);
5813     anArg.LowerCase();
5814     if (anArg == "-clear")
5815     {
5816       aContext->RemoveFilters();
5817     }
5818     else if (anArg == "-contextfilter" && anArgIter + 1 < theArgc)
5819     {
5820       TCollection_AsciiString aVal (theArgv[++anArgIter]);
5821       aVal.LowerCase();
5822       if (aVal == "and")
5823       {
5824         aContext->SetFilterType (SelectMgr_FilterType_AND);
5825       }
5826       else if (aVal == "or")
5827       {
5828         aContext->SetFilterType (SelectMgr_FilterType_OR);
5829       }
5830       else
5831       {
5832         Message::SendFail() << "Syntax error: wrong command attribute value '" << aVal << "'";
5833         return 1;
5834       }
5835     }
5836     else if (anArg == "-type"
5837           && anArgIter + 1 < theArgc)
5838     {
5839       TCollection_AsciiString aVal (theArgv[++anArgIter]);
5840       TopAbs_ShapeEnum aShapeType = TopAbs_COMPOUND;
5841       if (!TopAbs::ShapeTypeFromString (aVal.ToCString(), aShapeType))
5842       {
5843         Message::SendFail() << "Syntax error: wrong command attribute value '" << aVal << "'";
5844         return 1;
5845       }
5846
5847       Handle(SelectMgr_Filter) aFilter;
5848       if (aShapeType == TopAbs_SHAPE)
5849       {
5850         aFilter = new AIS_TypeFilter (AIS_KOI_Shape);
5851       }
5852       else
5853       {
5854         aFilter = new StdSelect_ShapeTypeFilter (aShapeType);
5855       }
5856       aContext->AddFilter (aFilter);
5857     }
5858     else if (anArg == "-secondtype"
5859           && anArgIter + 1 < theArgc)
5860     {
5861       TCollection_AsciiString aVal (theArgv[++anArgIter]);
5862       TopAbs_ShapeEnum aShapeType = TopAbs_COMPOUND;
5863       if (!TopAbs::ShapeTypeFromString (aVal.ToCString(), aShapeType))
5864       {
5865         Message::SendFail() << "Syntax error: wrong command attribute value '" << aVal << "'";
5866         return 1;
5867       }
5868
5869       Handle(SelectMgr_Filter) aFilter;
5870       if (aShapeType == TopAbs_SHAPE)
5871       {
5872         aFilter = new AIS_TypeFilter (AIS_KOI_Shape);
5873       }
5874       else
5875       {
5876         aFilter = new StdSelect_ShapeTypeFilter (aShapeType);
5877       }
5878       aContext->AddFilter (aFilter);
5879     }
5880     else
5881     {
5882       Message::SendFail() << "Syntax error: unknown argument '" << theArgv[anArgIter] << "'";
5883       return 1;
5884     }
5885   }
5886   return 0;
5887 }
5888
5889 //=======================================================================
5890 //function : VPickSelected
5891 //purpose  :
5892 //=======================================================================
5893 static int VPickSelected (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgs)
5894 {
5895   static Standard_Integer aCount = 0;
5896   TCollection_AsciiString aName = "PickedShape_";
5897
5898   if (theArgNb > 1)
5899   {
5900     aName = theArgs[1];
5901   }
5902   else
5903   {
5904     aName = aName + aCount++ + "_";
5905   }
5906
5907   Standard_Integer anIdx = 0;
5908   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected(), ++anIdx)
5909   {
5910     TopoDS_Shape aShape;
5911     if (TheAISContext()->HasSelectedShape())
5912     {
5913       aShape = TheAISContext()->SelectedShape();
5914     }
5915     else
5916     {
5917       Handle(AIS_InteractiveObject) IO = TheAISContext()->SelectedInteractive();
5918       aShape = Handle(AIS_Shape)::DownCast (IO)->Shape();
5919     }
5920
5921     TCollection_AsciiString aCurrentName = aName;
5922     if (anIdx > 0)
5923     {
5924       aCurrentName += anIdx;
5925     }
5926
5927     DBRep::Set ((aCurrentName).ToCString(), aShape);
5928
5929     Handle(AIS_Shape) aNewShape = new AIS_Shape (aShape);
5930     GetMapOfAIS().Bind (aNewShape, aCurrentName);
5931     TheAISContext()->Display (aNewShape, Standard_False);
5932   }
5933
5934   TheAISContext()->UpdateCurrentViewer();
5935
5936   return 0;
5937 }
5938
5939 //=======================================================================
5940 //function : list of known objects
5941 //purpose  :
5942 //=======================================================================
5943 static int VIOTypes( Draw_Interpretor& di, Standard_Integer , const char** )
5944 {
5945   //                             1234567890         12345678901234567         123456789
5946   TCollection_AsciiString Colum [3]={"Standard Types","Type Of Object","Signature"};
5947   TCollection_AsciiString BlankLine(64,'_');
5948   Standard_Integer i ;
5949
5950   di<<"/n"<<BlankLine.ToCString()<<"\n";
5951
5952   for( i =0;i<=2;i++)
5953     Colum[i].Center(20,' ');
5954   for(i=0;i<=2;i++)
5955     di<<"|"<<Colum[i].ToCString();
5956   di<<"|\n";
5957
5958   di<<BlankLine.ToCString()<<"\n";
5959
5960   //  TCollection_AsciiString thetypes[5]={"Datum","Shape","Object","Relation","None"};
5961   const char ** names = GetTypeNames();
5962
5963   TCollection_AsciiString curstring;
5964   TCollection_AsciiString curcolum[3];
5965
5966
5967   // les objets de type Datum..
5968   curcolum[1]+="Datum";
5969   for(i =0;i<=6;i++){
5970     curcolum[0].Clear();
5971     curcolum[0] += names[i];
5972
5973     curcolum[2].Clear();
5974     curcolum[2]+=TCollection_AsciiString(i+1);
5975
5976     for(Standard_Integer j =0;j<=2;j++){
5977       curcolum[j].Center(20,' ');
5978       di<<"|"<<curcolum[j].ToCString();
5979     }
5980     di<<"|\n";
5981   }
5982   di<<BlankLine.ToCString()<<"\n";
5983
5984   // les objets de type shape
5985   curcolum[1].Clear();
5986   curcolum[1]+="Shape";
5987   curcolum[1].Center(20,' ');
5988
5989   for(i=0;i<=2;i++){
5990     curcolum[0].Clear();
5991     curcolum[0] += names[7+i];
5992     curcolum[2].Clear();
5993     curcolum[2]+=TCollection_AsciiString(i);
5994
5995     for(Standard_Integer j =0;j<=2;j++){
5996       curcolum[j].Center(20,' ');
5997       di<<"|"<<curcolum[j].ToCString();
5998     }
5999     di<<"|\n";
6000   }
6001   di<<BlankLine.ToCString()<<"\n";
6002   // les IO de type objet...
6003   curcolum[1].Clear();
6004   curcolum[1]+="Object";
6005   curcolum[1].Center(20,' ');
6006   for(i=0;i<=1;i++){
6007     curcolum[0].Clear();
6008     curcolum[0] += names[10+i];
6009     curcolum[2].Clear();
6010     curcolum[2]+=TCollection_AsciiString(i);
6011
6012     for(Standard_Integer j =0;j<=2;j++){
6013       curcolum[j].Center(20,' ');
6014       di<<"|"<<curcolum[j].ToCString();
6015     }
6016     di<<"|\n";
6017   }
6018   di<<BlankLine.ToCString()<<"\n";
6019   // les contraintes et dimensions.
6020   // pour l'instant on separe juste contraintes et dimensions...
6021   // plus tard, on detaillera toutes les sortes...
6022   curcolum[1].Clear();
6023   curcolum[1]+="Relation";
6024   curcolum[1].Center(20,' ');
6025   for(i=0;i<=1;i++){
6026     curcolum[0].Clear();
6027     curcolum[0] += names[12+i];
6028     curcolum[2].Clear();
6029     curcolum[2]+=TCollection_AsciiString(i);
6030
6031     for(Standard_Integer j =0;j<=2;j++){
6032       curcolum[j].Center(20,' ');
6033       di<<"|"<<curcolum[j].ToCString();
6034     }
6035     di<<"|\n";
6036   }
6037   di<<BlankLine.ToCString()<<"\n";
6038
6039
6040   return 0;
6041 }
6042
6043
6044 static int VEraseType( Draw_Interpretor& , Standard_Integer argc, const char** argv)
6045 {
6046   if(argc!=2) return 1;
6047
6048   AIS_KindOfInteractive TheType;
6049   Standard_Integer TheSign(-1);
6050   GetTypeAndSignfromString(argv[1],TheType,TheSign);
6051
6052
6053   AIS_ListOfInteractive LIO;
6054
6055   // en attendant l'amelioration ais pour les dimensions...
6056   //
6057   Standard_Integer dimension_status(-1);
6058   if(TheType==AIS_KOI_Relation){
6059     dimension_status = TheSign ==1 ? 1 : 0;
6060     TheSign=-1;
6061   }
6062
6063   TheAISContext()->DisplayedObjects(TheType,TheSign,LIO);
6064   Handle(AIS_InteractiveObject) curio;
6065   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
6066     curio  = it.Value();
6067
6068     if(dimension_status == -1)
6069       TheAISContext()->Erase(curio,Standard_False);
6070     else {
6071       PrsDim_KindOfDimension KOD = Handle(PrsDim_Relation)::DownCast (curio)->KindOfDimension();
6072       if ((dimension_status==0 && KOD == PrsDim_KOD_NONE)||
6073           (dimension_status==1 && KOD != PrsDim_KOD_NONE))
6074         TheAISContext()->Erase(curio,Standard_False);
6075     }
6076   }
6077   TheAISContext()->UpdateCurrentViewer();
6078   return 0;
6079 }
6080 static int VDisplayType(Draw_Interpretor& , Standard_Integer argc, const char** argv)
6081 {
6082   if(argc!=2) return 1;
6083
6084   AIS_KindOfInteractive TheType;
6085   Standard_Integer TheSign(-1);
6086   GetTypeAndSignfromString(argv[1],TheType,TheSign);
6087
6088   // en attendant l'amelioration ais pour les dimensions...
6089   //
6090   Standard_Integer dimension_status(-1);
6091   if(TheType==AIS_KOI_Relation){
6092     dimension_status = TheSign ==1 ? 1 : 0;
6093     TheSign=-1;
6094   }
6095
6096   AIS_ListOfInteractive LIO;
6097   TheAISContext()->ObjectsInside(LIO,TheType,TheSign);
6098   Handle(AIS_InteractiveObject) curio;
6099   for(AIS_ListIteratorOfListOfInteractive it(LIO);it.More();it.Next()){
6100     curio  = it.Value();
6101     if(dimension_status == -1)
6102       TheAISContext()->Display(curio,Standard_False);
6103     else {
6104       PrsDim_KindOfDimension KOD = Handle(PrsDim_Relation)::DownCast (curio)->KindOfDimension();
6105       if ((dimension_status==0 && KOD == PrsDim_KOD_NONE)||
6106           (dimension_status==1 && KOD != PrsDim_KOD_NONE))
6107         TheAISContext()->Display(curio,Standard_False);
6108     }
6109
6110   }
6111
6112   TheAISContext()->UpdateCurrentViewer();
6113   return 0;
6114 }
6115
6116 static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a)
6117 {
6118   std::ifstream s(a[1]);
6119   BRep_Builder builder;
6120   TopoDS_Shape shape;
6121   BRepTools::Read(shape, s, builder);
6122   DBRep::Set(a[1], shape);
6123   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
6124   Handle(AIS_Shape) ais = new AIS_Shape(shape);
6125   Ctx->Display (ais, Standard_True);
6126   return 0;
6127 }
6128
6129 //===============================================================================================
6130 //function : VBsdf
6131 //purpose  :
6132 //===============================================================================================
6133 static int VBsdf (Draw_Interpretor& theDI,
6134                   Standard_Integer  theArgsNb,
6135                   const char**      theArgVec)
6136 {
6137   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
6138   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6139   if (aView.IsNull()
6140    || aViewer.IsNull())
6141   {
6142     Message::SendFail ("Error: No active viewer!");
6143     return 1;
6144   }
6145
6146   ViewerTest_CmdParser aCmd;
6147
6148   aCmd.SetDescription ("Adjusts parameters of material BSDF:");
6149
6150   aCmd.AddOption ("print|echo|p", "Prints BSDF");
6151
6152   aCmd.AddOption ("noupdate|update", "Suppresses viewer redraw call");
6153
6154   aCmd.AddOption ("kc", "Weight of coat specular/glossy BRDF");
6155   aCmd.AddOption ("kd", "Weight of base diffuse BRDF");
6156   aCmd.AddOption ("ks", "Weight of base specular/glossy BRDF");
6157   aCmd.AddOption ("kt", "Weight of base specular/glossy BTDF");
6158   aCmd.AddOption ("le", "Radiance emitted by surface");
6159
6160   aCmd.AddOption ("coatFresnel|cf", "Fresnel reflectance of coat layer. Allowed formats: Constant R, Schlick R G B, Dielectric N, Conductor N K");
6161   aCmd.AddOption ("baseFresnel|bf", "Fresnel reflectance of base layer. Allowed formats: Constant R, Schlick R G B, Dielectric N, Conductor N K");
6162
6163   aCmd.AddOption ("coatRoughness|cr", "Roughness of coat glossy BRDF");
6164   aCmd.AddOption ("baseRoughness|br", "Roughness of base glossy BRDF");
6165
6166   aCmd.AddOption ("absorpCoeff|af", "Absorption coeff of base transmission BTDF");
6167   aCmd.AddOption ("absorpColor|ac", "Absorption color of base transmission BTDF");
6168
6169   aCmd.AddOption ("normalize|n", "Normalizes BSDF to ensure energy conservation");
6170
6171   aCmd.Parse (theArgsNb, theArgVec);
6172
6173   if (aCmd.HasOption ("help"))
6174   {
6175     theDI.PrintHelp (theArgVec[0]);
6176     return 0;
6177   }
6178
6179   // check viewer update mode
6180   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
6181   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6182   {
6183     if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
6184     {
6185       break;
6186     }
6187   }
6188
6189   // find object
6190   TCollection_AsciiString aName (aCmd.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0).c_str());
6191   Handle(AIS_InteractiveObject) anIObj;
6192   if (!GetMapOfAIS().Find2 (aName, anIObj))
6193   {
6194     Message::SendFail ("Error: no active viewer");
6195     return 1;
6196   }
6197
6198   Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
6199   Graphic3d_BSDF aBSDF = aMaterial.BSDF();
6200
6201   if (aCmd.HasOption ("print"))
6202   {
6203     theDI << "\n"
6204       << "Kc:               " << aBSDF.Kc.r() << ", " << aBSDF.Kc.g() << ", " << aBSDF.Kc.b() << "\n"
6205       << "Kd:               " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
6206       << "Ks:               " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
6207       << "Kt:               " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
6208       << "Le:               " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n";
6209
6210     for (int aLayerID = 0; aLayerID < 2; ++aLayerID)
6211     {
6212       const Graphic3d_Vec4 aFresnel = aLayerID < 1 ? aBSDF.FresnelCoat.Serialize()
6213                                                    : aBSDF.FresnelBase.Serialize();
6214
6215       theDI << (aLayerID < 1 ? "Coat Fresnel:     "
6216                              : "Base Fresnel:     ");
6217
6218       if (aFresnel.x() >= 0.f)
6219       {
6220         theDI << "Schlick " << "R = " << aFresnel.r() << ", "
6221                             << "G = " << aFresnel.g() << ", "
6222                             << "B = " << aFresnel.b() << "\n";
6223       }
6224       else if (aFresnel.x() >= -1.5f)
6225       {
6226         theDI << "Constant " << aFresnel.z() << "\n";
6227       }
6228       else if (aFresnel.x() >= -2.5f)
6229       {
6230         theDI << "Conductor " << "N = " << aFresnel.y() << ", "
6231                               << "K = " << aFresnel.z() << "\n";
6232       }
6233       else
6234       {
6235         theDI << "Dielectric " << "N = " << aFresnel.y() << "\n";
6236       }
6237     }
6238
6239     theDI << "Coat roughness:   " << aBSDF.Kc.w() << "\n"
6240           << "Base roughness:   " << aBSDF.Ks.w() << "\n"
6241           << "Absorption coeff: " << aBSDF.Absorption.w() << "\n"
6242           << "Absorption color: " << aBSDF.Absorption.r() << ", "
6243                                   << aBSDF.Absorption.g() << ", "
6244                                   << aBSDF.Absorption.b() << "\n";
6245
6246     return 0;
6247   }
6248
6249   if (aCmd.HasOption ("coatRoughness", 1, Standard_True))
6250   {
6251     aBSDF.Kc.w() = aCmd.ArgFloat ("coatRoughness");
6252   }
6253
6254   if (aCmd.HasOption ("baseRoughness", 1, Standard_True))
6255   {
6256     aBSDF.Ks.w () = aCmd.ArgFloat ("baseRoughness");
6257   }
6258
6259   if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
6260   {
6261     aBSDF.Absorption.w() = aCmd.ArgFloat ("absorpCoeff");
6262   }
6263
6264   if (aCmd.HasOption ("absorpColor", 3, Standard_True))
6265   {
6266     const Graphic3d_Vec3 aRGB = aCmd.ArgVec3f ("absorpColor");
6267
6268     aBSDF.Absorption.r() = aRGB.r();
6269     aBSDF.Absorption.g() = aRGB.g();
6270     aBSDF.Absorption.b() = aRGB.b();
6271   }
6272
6273   if (aCmd.HasOption ("kc", 3) || aCmd.HasOption ("kc", 1, Standard_True))
6274   {
6275     Graphic3d_Vec3 aKc;
6276
6277     if (aCmd.HasOption ("kc", 3))
6278     {
6279       aKc = aCmd.ArgVec3f ("kc");
6280     }
6281     else
6282     {
6283       aKc = Graphic3d_Vec3 (aCmd.ArgFloat ("kc"));
6284     }
6285
6286     aBSDF.Kc.r() = aKc.r();
6287     aBSDF.Kc.g() = aKc.g();
6288     aBSDF.Kc.b() = aKc.b();
6289   }
6290
6291   if (aCmd.HasOption ("kd", 3))
6292   {
6293     aBSDF.Kd = aCmd.ArgVec3f ("kd");
6294   }
6295   else if (aCmd.HasOption ("kd", 1, Standard_True))
6296   {
6297     aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
6298   }
6299
6300   if (aCmd.HasOption ("ks", 3) || aCmd.HasOption ("ks", 1, Standard_True))
6301   {
6302     Graphic3d_Vec3 aKs;
6303
6304     if (aCmd.HasOption ("ks", 3))
6305     {
6306       aKs = aCmd.ArgVec3f ("ks");
6307     }
6308     else
6309     {
6310       aKs = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
6311     }
6312
6313     aBSDF.Ks.r() = aKs.r();
6314     aBSDF.Ks.g() = aKs.g();
6315     aBSDF.Ks.b() = aKs.b();
6316   }
6317
6318   if (aCmd.HasOption ("kt", 3))
6319   {
6320     aBSDF.Kt = aCmd.ArgVec3f ("kt");
6321   }
6322   else if (aCmd.HasOption ("kt", 1, Standard_True))
6323   {
6324     aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
6325   }
6326
6327   if (aCmd.HasOption ("le", 3))
6328   {
6329     aBSDF.Le = aCmd.ArgVec3f ("le");
6330   }
6331   else if (aCmd.HasOption ("le", 1, Standard_True))
6332   {
6333     aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
6334   }
6335
6336   const std::string aFresnelErrorMessage =
6337     "Error! Wrong Fresnel type. Allowed types are: Constant F, Schlick R G B, Dielectric N, Conductor N K\n";
6338
6339   for (int aLayerID = 0; aLayerID < 2; ++aLayerID)
6340   {
6341     const std::string aFresnel = aLayerID < 1 ? "baseFresnel"
6342                                               : "coatFresnel";
6343
6344     if (aCmd.HasOption (aFresnel, 4)) // Schlick: type R G B
6345     {
6346       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6347       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6348
6349       if (aFresnelType == "schlick")
6350       {
6351         Graphic3d_Vec3 aRGB (static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str())),
6352                              static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 2).c_str())),
6353                              static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 3).c_str())));
6354
6355         aRGB.r() = std::min (std::max (aRGB.r(), 0.f), 1.f);
6356         aRGB.g() = std::min (std::max (aRGB.g(), 0.f), 1.f);
6357         aRGB.b() = std::min (std::max (aRGB.b(), 0.f), 1.f);
6358
6359         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateSchlick (aRGB);
6360       }
6361       else
6362       {
6363         theDI << aFresnelErrorMessage.c_str() << "\n";
6364       }
6365     }
6366     else if (aCmd.HasOption (aFresnel, 3)) // Conductor: type N K
6367     {
6368       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6369       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6370
6371       if (aFresnelType == "conductor")
6372       {
6373         const float aN = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6374         const float aK = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 2).c_str()));
6375
6376         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateConductor (aN, aK);
6377       }
6378       else
6379       {
6380         theDI << aFresnelErrorMessage.c_str() << "\n";
6381       }
6382     }
6383     else if (aCmd.HasOption (aFresnel, 2)) // Dielectric or Constant: type N|C
6384     {
6385       std::string aFresnelType = aCmd.Arg (aFresnel, 0);
6386       std::transform (aFresnelType.begin (), aFresnelType.end (), aFresnelType.begin (), ::LowerCase);
6387
6388       if (aFresnelType == "constant")
6389       {
6390         const float aR = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6391
6392         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateConstant (aR);
6393       }
6394       else if (aFresnelType == "dielectric")
6395       {
6396         const float aN = static_cast<float> (Draw::Atof (aCmd.Arg (aFresnel, 1).c_str()));
6397
6398         (aLayerID < 1 ? aBSDF.FresnelBase : aBSDF.FresnelCoat) = Graphic3d_Fresnel::CreateDielectric (aN);
6399       }
6400       else
6401       {
6402         theDI << aFresnelErrorMessage.c_str() << "\n";
6403       }
6404     }
6405   }
6406
6407   if (aCmd.HasOption ("normalize"))
6408   {
6409     aBSDF.Normalize();
6410   }
6411
6412   aMaterial.SetBSDF (aBSDF);
6413   anIObj->SetMaterial (aMaterial);
6414
6415   return 0;
6416 }
6417
6418 //==============================================================================
6419 //function : VLoadSelection
6420 //purpose  : Adds given objects to map of AIS and loads selection primitives for them
6421 //==============================================================================
6422 static Standard_Integer VLoadSelection (Draw_Interpretor& /*theDi*/,
6423                                         Standard_Integer theArgNb,
6424                                         const char** theArgVec)
6425 {
6426   if (theArgNb < 2)
6427   {
6428     Message::SendFail ("Syntax error: wrong number of arguments.");
6429     return 1;
6430   }
6431
6432   Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
6433   if (aCtx.IsNull())
6434   {
6435     ViewerTest::ViewerInit();
6436     aCtx = ViewerTest::GetAISContext();
6437   }
6438
6439   // Parse input arguments
6440   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6441   {
6442     const TCollection_AsciiString aName = theArgVec[anArgIter];
6443     Handle(AIS_InteractiveObject) aShape;
6444     if (!GetMapOfAIS().Find2 (aName, aShape))
6445     {
6446       TopoDS_Shape aDrawShape = DBRep::GetExisting (aName);
6447       if (!aDrawShape.IsNull())
6448       {
6449         aShape = new AIS_Shape (aDrawShape);
6450         GetMapOfAIS().Bind (aShape, aName);
6451       }
6452     }
6453     if (aShape.IsNull())
6454     {
6455       Message::SendFail() << "Syntax error: presentation '" << aName << "' not found";
6456       return 1;
6457     }
6458
6459     aCtx->Load (aShape, -1);
6460     aCtx->Activate (aShape, aShape->GlobalSelectionMode(), Standard_True);
6461   }
6462   return 0;
6463 }
6464
6465 //==============================================================================
6466 //function : ViewerTest::Commands
6467 //purpose  : Add all the viewer command in the Draw_Interpretor
6468 //==============================================================================
6469
6470 void ViewerTest::Commands(Draw_Interpretor& theCommands)
6471 {
6472   ViewerTest::ViewerCommands(theCommands);
6473   ViewerTest::RelationCommands(theCommands);
6474   ViewerTest::ObjectCommands(theCommands);
6475   ViewerTest::FilletCommands(theCommands);
6476   ViewerTest::OpenGlCommands(theCommands);
6477
6478   const char *group = "AIS_Display";
6479
6480   // display
6481   theCommands.Add("visos",
6482       "visos [name1 ...] [nbUIsos nbVIsos IsoOnPlane(0|1)]\n"
6483       "\tIf last 3 optional parameters are not set prints numbers of U-, V- isolines and IsoOnPlane.\n",
6484       __FILE__, visos, group);
6485
6486   theCommands.Add("vdisplay",
6487               "vdisplay [-noupdate|-update] [-local] [-mutable] [-neutral]"
6488       "\n\t\t:          [-trsfPers {zoom|rotate|zoomRotate|none}=none]"
6489       "\n\t\t:                            [-trsfPersPos X Y [Z]] [-3d]"
6490       "\n\t\t:          [-2d|-trihedron [{top|bottom|left|right|topLeft"
6491       "\n\t\t:                           |topRight|bottomLeft|bottomRight}"
6492       "\n\t\t:                                         [offsetX offsetY]]]"
6493       "\n\t\t:          [-dispMode mode] [-highMode mode]"
6494       "\n\t\t:          [-layer index] [-top|-topmost|-overlay|-underlay]"
6495       "\n\t\t:          [-redisplay] [-erased]"
6496       "\n\t\t:          name1 [name2] ... [name n]"
6497       "\n\t\t: Displays named objects."
6498       "\n\t\t: Option -local enables displaying of objects in local"
6499       "\n\t\t: selection context. Local selection context will be opened"
6500       "\n\t\t: if there is not any."
6501       "\n\t\t:  -noupdate    Suppresses viewer redraw call."
6502       "\n\t\t:  -mutable     Enables optimizations for mutable objects."
6503       "\n\t\t:  -neutral     Draws objects in main viewer."
6504       "\n\t\t:  -erased      Loads the object into context, but does not display it."
6505       "\n\t\t:  -layer       Sets z-layer for objects."
6506       "\n\t\t:               Alternatively -overlay|-underlay|-top|-topmost"
6507       "\n\t\t:               options can be used for the default z-layers."
6508       "\n\t\t:  -top         Draws object on top of main presentations"
6509       "\n\t\t:               but below topmost."
6510       "\n\t\t:  -topmost     Draws in overlay for 3D presentations."
6511       "\n\t\t:               with independent Depth."
6512       "\n\t\t:  -overlay     Draws objects in overlay for 2D presentations."
6513       "\n\t\t:               (On-Screen-Display)"
6514       "\n\t\t:  -underlay    Draws objects in underlay for 2D presentations."
6515       "\n\t\t:               (On-Screen-Display)"
6516       "\n\t\t:  -selectable|-noselect Controls selection of objects."
6517       "\n\t\t:  -trsfPers    Sets a transform persistence flags."
6518       "\n\t\t:  -trsfPersPos Sets an anchor point for transform persistence."
6519       "\n\t\t:  -2d          Displays object in screen coordinates."
6520       "\n\t\t:               (DY looks up)"
6521       "\n\t\t:  -dispmode    Sets display mode for objects."
6522       "\n\t\t:  -highmode    Sets hilight mode for objects."
6523       "\n\t\t:  -redisplay   Recomputes presentation of objects.",
6524       __FILE__, VDisplay2, group);
6525
6526   theCommands.Add ("vnbdisplayed",
6527       "vnbdisplayed"
6528       "\n\t\t: Returns number of displayed objects",
6529       __FILE__, VNbDisplayed, group);
6530
6531   theCommands.Add ("vupdate",
6532       "vupdate name1 [name2] ... [name n]"
6533       "\n\t\t: Updates named objects in interactive context",
6534       __FILE__, VUpdate, group);
6535
6536   theCommands.Add("verase",
6537       "verase [-noupdate|-update] [-local] [name1] ...  [name n] [-noerror]"
6538       "\n\t\t: Erases selected or named objects."
6539       "\n\t\t: If there are no selected or named objects the whole viewer is erased."
6540       "\n\t\t: Option -local enables erasing of selected or named objects without"
6541       "\n\t\t: closing local selection context."
6542       "\n\t\t: Option -noerror prevents exception on non-existing objects.",
6543       __FILE__, VErase, group);
6544
6545   theCommands.Add("vremove",
6546       "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ...  [name n] [-noerror]"
6547       "or vremove [-context] -all to remove all objects"
6548       "\n\t\t: Removes selected or named objects."
6549       "\n\t\t  If -context is in arguments, the objects are not deleted"
6550       "\n\t\t  from the map of objects and names."
6551       "\n\t\t: Option -local enables removing of selected or named objects without"
6552       "\n\t\t: closing local selection context. Empty local selection context will be"
6553       "\n\t\t: closed."
6554       "\n\t\t: Option -noupdate suppresses viewer redraw call."
6555       "\n\t\t: Option -noinfo suppresses displaying the list of removed objects."
6556       "\n\t\t: Option -noerror prevents exception on non-existing objects.",
6557       __FILE__, VRemove, group);
6558
6559   theCommands.Add("vdonly",
6560                   "vdonly [-noupdate|-update] [name1] ...  [name n]"
6561       "\n\t\t: Displays only selected or named objects",
6562                   __FILE__,VDonly2,group);
6563
6564   theCommands.Add("vdisplayall",
6565       "vdisplayall"
6566       "\n\t\t: Displays all erased interactive objects (see vdir and vstate).",
6567       __FILE__, VDisplayAll, group);
6568
6569   theCommands.Add("veraseall",
6570       "veraseall"
6571       "\n\t\t: Erases all objects displayed in the viewer.",
6572       __FILE__, VErase, group);
6573
6574   theCommands.Add("verasetype",
6575       "verasetype <Type>"
6576       "\n\t\t: Erase all the displayed objects of one given kind (see vtypes)",
6577       __FILE__, VEraseType, group);
6578   theCommands.Add("vbounding",
6579               "vbounding [-noupdate|-update] [-mode] name1 [name2 [...]]"
6580       "\n\t\t:           [-print] [-hide]"
6581       "\n\t\t: Temporarily display bounding box of specified Interactive"
6582       "\n\t\t: Objects, or print it to console if -print is specified."
6583       "\n\t\t: Already displayed box might be hidden by -hide option.",
6584                   __FILE__,VBounding,group);
6585
6586   theCommands.Add("vdisplaytype",
6587                   "vdisplaytype        : vdisplaytype <Type> <Signature> \n\t display all the objects of one given kind (see vtypes) which are stored the AISContext ",
6588                   __FILE__,VDisplayType,group);
6589
6590   theCommands.Add("vsetdispmode",
6591                   "vsetdispmode [name] mode(1,2,..)"
6592       "\n\t\t: Sets display mode for all, selected or named objects.",
6593                   __FILE__,VDispMode,group);
6594
6595   theCommands.Add("vunsetdispmode",
6596                   "vunsetdispmode [name]"
6597       "\n\t\t: Unsets custom display mode for selected or named objects.",
6598                   __FILE__,VDispMode,group);
6599
6600   theCommands.Add("vdir",
6601               "vdir [mask] [-list]"
6602       "\n\t\t: Lists all objects displayed in 3D viewer"
6603       "\n\t\t:    mask - name filter like prefix*"
6604       "\n\t\t:   -list - format list with new-line per name; OFF by default",
6605                   __FILE__,VDir,group);
6606
6607 #ifdef HAVE_FREEIMAGE
6608   #define DUMP_FORMATS "{png|bmp|jpg|gif}"
6609 #else
6610   #define DUMP_FORMATS "{ppm}"
6611 #endif
6612   theCommands.Add("vdump",
6613               "vdump <filename>." DUMP_FORMATS " [-width Width -height Height]"
6614       "\n\t\t:       [-buffer rgb|rgba|depth=rgb]"
6615       "\n\t\t:       [-stereo mono|left|right|blend|sideBySide|overUnder=mono]"
6616       "\n\t\t:       [-xrPose base|head|handLeft|handRight=base]"
6617       "\n\t\t:       [-tileSize Size=0]"
6618       "\n\t\t: Dumps content of the active view into image file",
6619                   __FILE__,VDump,group);
6620
6621   theCommands.Add("vsub",      "vsub 0/1 (off/on) [obj]        : Subintensity(on/off) of selected objects",
6622                   __FILE__,VSubInt,group);
6623
6624   theCommands.Add("vaspects",
6625               "vaspects [-noupdate|-update] [name1 [name2 [...]] | -defaults] [-subshapes subname1 [subname2 [...]]]"
6626       "\n\t\t:          [-visibility {0|1}]"
6627       "\n\t\t:          [-color {ColorName | R G B}] [-unsetColor]"
6628       "\n\t\t:          [-backfaceColor Color]"
6629       "\n\t\t:          [-material MatName] [-unsetMaterial]"
6630       "\n\t\t:          [-transparency Transp] [-unsetTransparency]"
6631       "\n\t\t:          [-width LineWidth] [-unsetWidth]"
6632       "\n\t\t:          [-lineType {solid|dash|dot|dotDash|0xHexPattern} [-stippleFactor factor]]"
6633       "\n\t\t:          [-unsetLineType]"
6634       "\n\t\t:          [-markerType {.|+|x|O|xcircle|pointcircle|ring1|ring2|ring3|ball|ImagePath}]"
6635       "\n\t\t:          [-unsetMarkerType]"
6636       "\n\t\t:          [-markerSize Scale] [-unsetMarkerSize]"
6637       "\n\t\t:          [-freeBoundary {0|1}]"
6638       "\n\t\t:          [-freeBoundaryWidth Width] [-unsetFreeBoundaryWidth]"
6639       "\n\t\t:          [-freeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]"
6640       "\n\t\t:          [-isoOnTriangulation 0|1]"
6641       "\n\t\t:          [-maxParamValue {value}]"
6642       "\n\t\t:          [-sensitivity {selection_mode} {value}]"
6643       "\n\t\t:          [-shadingModel {unlit|flat|gouraud|phong|pbr|pbr_facet}]"
6644       "\n\t\t:          [-unsetShadingModel]"
6645       "\n\t\t:          [-interior {solid|hatch|hidenline|point}] [-setHatch HatchStyle]"
6646       "\n\t\t:          [-unsetInterior]"
6647       "\n\t\t:          [-faceBoundaryDraw {0|1}] [-mostContinuity {c0|c1|c2|c3|cn}]"
6648       "\n\t\t:          [-faceBoundaryWidth LineWidth] [-faceBoundaryColor R G B] [-faceBoundaryType LineType]"
6649       "\n\t\t:          [-drawEdges {0|1}] [-edgeType LineType] [-edgeColor R G B] [-quadEdges {0|1}]"
6650       "\n\t\t:          [-drawSilhouette {0|1}]"
6651       "\n\t\t:          [-alphaMode {opaque|mask|blend|blendauto} [alphaCutOff=0.5]]"
6652       "\n\t\t:          [-dumpJson]"
6653       "\n\t\t:          [-dumpCompact {0|1}]"
6654       "\n\t\t:          [-dumpDepth depth]"
6655       "\n\t\t: Manage presentation properties of all, selected or named objects."
6656       "\n\t\t: When -subshapes is specified than following properties will be assigned to specified sub-shapes."
6657       "\n\t\t: When -defaults is specified than presentation properties will be"
6658       "\n\t\t: assigned to all objects that have not their own specified properties"
6659       "\n\t\t: and to all objects to be displayed in the future."
6660       "\n\t\t: If -defaults is used there should not be any objects' names nor -subshapes specifier."
6661       "\n\t\t: See also vlistcolors and vlistmaterials to list named colors and materials"
6662       "\n\t\t: accepted by arguments -material and -color",
6663                   __FILE__,VAspects,group);
6664
6665   theCommands.Add("vsetcolor",
6666       "vsetcolor [-noupdate|-update] [name] ColorName"
6667       "\n\t\t: Sets color for all, selected or named objects."
6668       "\n\t\t: Alias for vaspects -setcolor [name] ColorName.",
6669                   __FILE__,VAspects,group);
6670
6671   theCommands.Add("vunsetcolor",
6672                   "vunsetcolor [-noupdate|-update] [name]"
6673       "\n\t\t: Resets color for all, selected or named objects."
6674       "\n\t\t: Alias for vaspects -unsetcolor [name].",
6675                   __FILE__,VAspects,group);
6676
6677   theCommands.Add("vsettransparency",
6678                   "vsettransparency [-noupdate|-update] [name] Coefficient"
6679       "\n\t\t: Sets transparency for all, selected or named objects."
6680       "\n\t\t: The Coefficient may be between 0.0 (opaque) and 1.0 (fully transparent)."
6681       "\n\t\t: Alias for vaspects -settransp [name] Coefficient.",
6682                   __FILE__,VAspects,group);
6683
6684   theCommands.Add("vunsettransparency",
6685                   "vunsettransparency [-noupdate|-update] [name]"
6686       "\n\t\t: Resets transparency for all, selected or named objects."
6687       "\n\t\t: Alias for vaspects -unsettransp [name].",
6688                   __FILE__,VAspects,group);
6689
6690   theCommands.Add("vsetmaterial",
6691                   "vsetmaterial [-noupdate|-update] [name] MaterialName"
6692       "\n\t\t: Alias for vaspects -setmaterial [name] MaterialName.",
6693                   __FILE__,VAspects,group);
6694
6695   theCommands.Add("vunsetmaterial",
6696                   "vunsetmaterial [-noupdate|-update] [name]"
6697       "\n\t\t: Alias for vaspects -unsetmaterial [name].",
6698                   __FILE__,VAspects,group);
6699
6700   theCommands.Add("vsetwidth",
6701                   "vsetwidth [-noupdate|-update] [name] width(0->10)"
6702       "\n\t\t: Alias for vaspects -setwidth [name] width.",
6703                   __FILE__,VAspects,group);
6704
6705   theCommands.Add("vunsetwidth",
6706                   "vunsetwidth [-noupdate|-update] [name]"
6707       "\n\t\t: Alias for vaspects -unsetwidth [name].",
6708                   __FILE__,VAspects,group);
6709
6710   theCommands.Add("vsetinteriorstyle",
6711     "vsetinteriorstyle [-noupdate|-update] [name] Style"
6712     "\n\t\t: Alias for vaspects -setInterior [name] Style.",
6713                   __FILE__,VAspects,group);
6714
6715   theCommands.Add ("vsetedgetype",
6716     "vsetedgetype [name] [-type {solid, dash, dot}] [-color R G B] [-width value]"
6717     "\n\t\t: Alias for vaspects [name] -setEdgeType Type.",
6718       __FILE__, VAspects, group);
6719
6720   theCommands.Add ("vunsetedgetype",
6721     "vunsetedgetype [name]"
6722     "\n\t\t: Alias for vaspects [name] -unsetEdgeType.",
6723       __FILE__, VAspects, group);
6724
6725   theCommands.Add ("vshowfaceboundary",
6726     "vshowfaceboundary [name]"
6727     "\n\t\t: Alias for vaspects [name] -setFaceBoundaryDraw on",
6728       __FILE__, VAspects, group);
6729
6730   theCommands.Add("vsensdis",
6731       "vsensdis : Display active entities (sensitive entities of one of the standard types corresponding to active selection modes)."
6732       "\n\t\t: Standard entity types are those defined in Select3D package:"
6733       "\n\t\t: - sensitive box"
6734       "\n\t\t: - sensitive face"
6735       "\n\t\t: - sensitive curve"
6736       "\n\t\t: - sensitive segment"
6737       "\n\t\t: - sensitive circle"
6738       "\n\t\t: - sensitive point"
6739       "\n\t\t: - sensitive triangulation"
6740       "\n\t\t: - sensitive triangle"
6741       "\n\t\t: Custom(application - defined) sensitive entity types are not processed by this command.",
6742       __FILE__,VDispSensi,group);
6743
6744   theCommands.Add("vsensera",
6745       "vsensera : erase active entities",
6746       __FILE__,VClearSensi,group);
6747
6748   theCommands.Add("vsetshading",
6749       "vsetshading  : vsetshading name Quality(default=0.0008) "
6750       "\n\t\t: Sets deflection coefficient that defines the quality of the shape representation in the shading mode.",
6751       __FILE__,VShading,group);
6752
6753   theCommands.Add("vunsetshading",
6754       "vunsetshading :vunsetshading name "
6755       "\n\t\t: Sets default deflection coefficient (0.0008) that defines the quality of the shape representation in the shading mode.",
6756       __FILE__,VShading,group);
6757
6758   theCommands.Add ("vtexture",
6759                    "vtexture [-noupdate|-update] name [ImageFile|IdOfTexture|off]"
6760                    "\n\t\t:          [-tex0 Image0] [-tex1 Image1] [...]"
6761                    "\n\t\t:          [-origin {u v|off}] [-scale {u v|off}] [-repeat {u v|off}]"
6762                    "\n\t\t:          [-trsfTrans du dv] [-trsfScale su sv] [-trsfAngle Angle]"
6763                    "\n\t\t:          [-modulate {on|off}]"
6764                    "\n\t\t:          [-setFilter {nearest|bilinear|trilinear}]"
6765                    "\n\t\t:          [-setAnisoFilter {off|low|middle|quality}]"
6766                    "\n\t\t:          [-default]"
6767                    "\n\t\t: The texture can be specified by filepath"
6768                    "\n\t\t: or as ID (0<=IdOfTexture<=20) specifying one of the predefined textures."
6769                    "\n\t\t: The options are:"
6770                    "\n\t\t:   -scale     Setup texture scaling for generating coordinates; (1, 1) by default"
6771                    "\n\t\t:   -origin    Setup texture origin  for generating coordinates; (0, 0) by default"
6772                    "\n\t\t:   -repeat    Setup texture repeat  for generating coordinates; (1, 1) by default"
6773                    "\n\t\t:   -modulate  Enable or disable texture color modulation"
6774                    "\n\t\t:   -trsfAngle Setup dynamic texture coordinates transformation - rotation angle"
6775                    "\n\t\t:   -trsfTrans Setup dynamic texture coordinates transformation - translation vector"
6776                    "\n\t\t:   -trsfScale Setup dynamic texture coordinates transformation - scale vector"
6777                    "\n\t\t:   -setFilter Setup texture filter"
6778                    "\n\t\t:   -setAnisoFilter Setup anisotropic filter for texture with mip-levels"
6779                    "\n\t\t:   -default   Sets texture mapping default parameters",
6780                     __FILE__, VTexture, group);
6781
6782   theCommands.Add("vtexscale",
6783                   "vtexscale name ScaleU ScaleV"
6784                   "\n\t\t: Alias for vtexture name -setScale ScaleU ScaleV.",
6785                   __FILE__,VTexture,group);
6786
6787   theCommands.Add("vtexorigin",
6788                   "vtexorigin name OriginU OriginV"
6789                   "\n\t\t: Alias for vtexture name -setOrigin OriginU OriginV.",
6790                   __FILE__,VTexture,group);
6791
6792   theCommands.Add("vtexrepeat",
6793                   "vtexrepeat name RepeatU RepeatV"
6794                   "\n\t\t: Alias for vtexture name -setRepeat RepeatU RepeatV.",
6795                   VTexture,group);
6796
6797   theCommands.Add("vtexdefault",
6798                   "vtexdefault name"
6799                   "\n\t\t: Alias for vtexture name -default.",
6800                   VTexture,group);
6801
6802   theCommands.Add("vstate",
6803       "vstate [-entities] [-hasSelected] [name1] ... [nameN]"
6804       "\n\t\t: Reports show/hidden state for selected or named objects"
6805       "\n\t\t:   -entities - print low-level information about detected entities"
6806       "\n\t\t:   -hasSelected - prints 1 if context has selected shape and 0 otherwise",
6807                   __FILE__,VState,group);
6808
6809   theCommands.Add("vpickshapes",
6810                   "vpickshape subtype(VERTEX,EDGE,WIRE,FACE,SHELL,SOLID) [name1 or .] [name2 or .] [name n or .]"
6811                   "\n\t\t: Hold Ctrl and pick object by clicking Left mouse button."
6812                   "\n\t\t: Hold also Shift for multiple selection.",
6813                   __FILE__, VPickShape, group);
6814
6815   theCommands.Add("vtypes",
6816                   "vtypes : list of known types and signatures in AIS - To be Used in vpickobject command for selection with filters",
6817                   VIOTypes,group);
6818
6819   theCommands.Add("vr",
6820       "vr filename"
6821       "\n\t\t: Reads shape from BREP-format file and displays it in the viewer. ",
6822                   __FILE__,vr, group);
6823
6824   theCommands.Add("vselfilter",
6825     "vselfilter [-contextfilter {AND|OR}]"
6826     "\n         [-type {VERTEX|EDGE|WIRE|FACE|SHAPE|SHELL|SOLID}]"
6827     "\n         [-secondtype {VERTEX|EDGE|WIRE|FACE|SHAPE|SHELL|SOLID}]"
6828     "\n         [-clear]"
6829     "\nSets selection shape type filter in context or remove all filters."
6830     "\n    : Option -contextfilter : To define a selection filter for two or more types of entity,"
6831     "\n                              use value AND (OR by default)."
6832     "\n    : Option -type set type of selection filter. Filters are applyed with Or combination."
6833     "\n    : Option -clear remove all filters in context",
6834                   __FILE__,VSelFilter,group);
6835
6836   theCommands.Add("vpickselected", "vpickselected [name]: extract selected shape.",
6837     __FILE__, VPickSelected, group);
6838
6839   theCommands.Add ("vloadselection",
6840     "vloadselection [-context] [name1] ... [nameN] : allows to load selection"
6841     "\n\t\t: primitives for the shapes with names given without displaying them.",
6842     __FILE__, VLoadSelection, group);
6843
6844   theCommands.Add("vbsdf", "vbsdf [name] [options]"
6845     "\nAdjusts parameters of material BSDF:"
6846     "\n    -help : Shows this message"
6847     "\n    -print : Print BSDF"
6848     "\n    -kd : Weight of the Lambertian BRDF"
6849     "\n    -kr : Weight of the reflection BRDF"
6850     "\n    -kt : Weight of the transmission BTDF"
6851     "\n    -ks : Weight of the glossy Blinn BRDF"
6852     "\n    -le : Self-emitted radiance"
6853     "\n    -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
6854     "\n               Schlick x y z, Dielectric x, Conductor x y"
6855     "\n    -roughness : Roughness of material (Blinn's exponent)"
6856     "\n    -absorpcoeff : Absorption coefficient (only for transparent material)"
6857     "\n    -absorpcolor : Absorption color (only for transparent material)"
6858     "\n    -normalize : Normalize BSDF coefficients",
6859     __FILE__, VBsdf, group);
6860
6861 }
6862
6863 //=====================================================================
6864 //========================= for testing Draft and Rib =================
6865 //=====================================================================
6866 #include <BRepOffsetAPI_MakeThickSolid.hxx>
6867 #include <DBRep.hxx>
6868 #include <TopoDS_Face.hxx>
6869 #include <gp_Pln.hxx>
6870 #include <BRepOffsetAPI_DraftAngle.hxx>
6871 #include <Precision.hxx>
6872 #include <BRepAlgo.hxx>
6873 #include <OSD_Environment.hxx>
6874 #include <DrawTrSurf.hxx>
6875
6876 //=======================================================================
6877 //function : IsValid
6878 //purpose  :
6879 //=======================================================================
6880 static Standard_Boolean IsValid(const TopTools_ListOfShape& theArgs,
6881                                 const TopoDS_Shape& theResult,
6882                                 const Standard_Boolean closedSolid,
6883                                 const Standard_Boolean GeomCtrl)
6884 {
6885   OSD_Environment check ("DONT_SWITCH_IS_VALID") ;
6886   TCollection_AsciiString checkValid = check.Value();
6887   Standard_Boolean ToCheck = Standard_True;
6888   if (!checkValid.IsEmpty()) {
6889 #ifdef OCCT_DEBUG
6890     std::cout <<"DONT_SWITCH_IS_VALID positionnee a :"<<checkValid.ToCString()<<"\n";
6891 #endif
6892     if ( checkValid=="true" || checkValid=="TRUE" ) {
6893       ToCheck= Standard_False;
6894     }
6895   } else {
6896 #ifdef OCCT_DEBUG
6897     std::cout <<"DONT_SWITCH_IS_VALID non positionne\n";
6898 #endif
6899   }
6900   Standard_Boolean IsValid = Standard_True;
6901   if (ToCheck)
6902     IsValid = BRepAlgo::IsValid(theArgs,theResult,closedSolid,GeomCtrl) ;
6903   return IsValid;
6904
6905 }
6906
6907 //===============================================================================
6908 // TDraft : test draft, uses AIS Viewer
6909 // Solid Face Plane Angle  Reverse
6910 //===============================================================================
6911 static Standard_Integer TDraft(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
6912 {
6913   if (argc < 5) return 1;
6914 // argv[1] - TopoDS_Shape Solid
6915 // argv[2] - TopoDS_Shape Face
6916 // argv[3] - TopoDS_Shape Plane
6917 // argv[4] - Standard_Real Angle
6918 // argv[5] - Standard_Integer Reverse
6919
6920 //  Sprintf(prefix, argv[1]);
6921   Standard_Real anAngle = 0;
6922   Standard_Boolean Rev = Standard_False;
6923   Standard_Integer rev = 0;
6924   TopoDS_Shape Solid  = DBRep::Get (argv[1]);
6925   TopoDS_Shape face   = DBRep::Get (argv[2]);
6926   TopoDS_Face Face    = TopoDS::Face(face);
6927   TopoDS_Shape Plane  = DBRep::Get (argv[3]);
6928   if (Plane.IsNull ()) {
6929     di << "TEST : Plane is NULL\n";
6930     return 1;
6931   }
6932   anAngle = Draw::Atof(argv[4]);
6933   anAngle = 2*M_PI * anAngle / 360.0;
6934   gp_Pln aPln;
6935   Handle( Geom_Surface )aSurf;
6936   PrsDim_KindOfSurface aSurfType;
6937   Standard_Real Offset;
6938   gp_Dir aDir;
6939   if(argc > 4) { // == 5
6940     rev = Draw::Atoi(argv[5]);
6941     Rev = (rev)? Standard_True : Standard_False;
6942   }
6943
6944   TopoDS_Face face2 = TopoDS::Face(Plane);
6945   if(!PrsDim::GetPlaneFromFace(face2, aPln, aSurf, aSurfType, Offset))
6946     {
6947       di << "TEST : Can't find plane\n";
6948       return 1;
6949     }
6950
6951   aDir = aPln.Axis().Direction();
6952   if (!aPln.Direct())
6953     aDir.Reverse();
6954   if (Plane.Orientation() == TopAbs_REVERSED)
6955     aDir.Reverse();
6956   di << "TEST : gp::Resolution() = " << gp::Resolution() << "\n";
6957
6958   BRepOffsetAPI_DraftAngle Draft (Solid);
6959
6960   if(Abs(anAngle)< Precision::Angular()) {
6961     di << "TEST : NULL angle\n";
6962     return 1;}
6963
6964   if(Rev) anAngle = - anAngle;
6965   Draft.Add (Face, aDir, anAngle, aPln);
6966   Draft.Build ();
6967   if (!Draft.IsDone())  {
6968     di << "TEST : Draft Not DONE \n";
6969     return 1;
6970   }
6971   TopTools_ListOfShape Larg;
6972   Larg.Append(Solid);
6973   if (!IsValid(Larg,Draft.Shape(),Standard_True,Standard_False)) {
6974     di << "TEST : DesignAlgo returns Not valid\n";
6975     return 1;
6976   }
6977
6978   Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
6979   Handle(AIS_Shape) ais = new AIS_Shape(Draft.Shape());
6980
6981   if ( !ais.IsNull() ) {
6982     ais->SetColor(DEFAULT_COLOR);
6983     ais->SetMaterial(DEFAULT_MATERIAL);
6984     // Display the AIS_Shape without redraw
6985     Ctx->Display(ais, Standard_False);
6986
6987     const char *Name = "draft1";
6988     Handle(AIS_InteractiveObject) an_object;
6989     if (GetMapOfAIS().Find2(Name, an_object))
6990     {
6991       if (!an_object.IsNull())
6992       {
6993         Ctx->Remove (an_object, Standard_True);
6994       }
6995       GetMapOfAIS().UnBind2 (Name);
6996     }
6997     GetMapOfAIS().Bind(ais, Name);
6998 //  DBRep::Set("draft", ais->Shape());
6999   }
7000   Ctx->Display(ais, Standard_True);
7001   return 0;
7002 }
7003
7004 //==============================================================================
7005 //function : splitParameter
7006 //purpose  : Split parameter string to parameter name and parameter value
7007 //==============================================================================
7008 Standard_Boolean ViewerTest::SplitParameter (const TCollection_AsciiString& theString,
7009                                              TCollection_AsciiString&       theName,
7010                                              TCollection_AsciiString&       theValue)
7011 {
7012   Standard_Integer aParamNameEnd = theString.FirstLocationInSet ("=", 1, theString.Length());
7013
7014   if (aParamNameEnd == 0)
7015   {
7016     return Standard_False;
7017   }
7018
7019   TCollection_AsciiString aString (theString);
7020   if (aParamNameEnd != 0)
7021   {
7022     theValue = aString.Split (aParamNameEnd);
7023     aString.Split (aString.Length() - 1);
7024     theName = aString;
7025   }
7026
7027   return Standard_True;
7028 }
7029
7030 //============================================================================
7031 //  MyCommands
7032 //============================================================================
7033 void ViewerTest::MyCommands( Draw_Interpretor& theCommands)
7034 {
7035
7036   DrawTrSurf::BasicCommands(theCommands);
7037   const char* group = "Check Features Operations commands";
7038
7039   theCommands.Add("Draft","Draft    Solid Face Plane Angle Reverse",
7040                   __FILE__,
7041                   &TDraft,group); //Draft_Modification
7042 }
7043
7044 //==============================================================================
7045 // ViewerTest::Factory
7046 //==============================================================================
7047 void ViewerTest::Factory(Draw_Interpretor& theDI)
7048 {
7049   // definition of Viewer Command
7050   ViewerTest::Commands(theDI);
7051
7052 #ifdef OCCT_DEBUG
7053       theDI << "Draw Plugin : OCC V2d & V3d commands are loaded\n";
7054 #endif
7055 }
7056
7057 // Declare entry point PLUGINFACTORY
7058 DPLUGIN(ViewerTest)