0031221: Visualization - selection filter in context
[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     }