0029902: Data Exchange, XCAF - provide extended Material definition for visualization...
[occt.git] / src / XDEDRAW / XDEDRAW_Colors.cxx
1 // Created on: 2000-08-04
2 // Created by: Pavel TELKOV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <DBRep.hxx>
18 #include <DDocStd.hxx>
19 #include <Draw.hxx>
20 #include <Precision.hxx>
21 #include <Quantity_Color.hxx>
22 #include <Quantity_ColorRGBA.hxx>
23 #include <OSD_File.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TDF_Label.hxx>
26 #include <TDF_LabelSequence.hxx>
27 #include <TDF_Tool.hxx>
28 #include <TDataStd_Name.hxx>
29 #include <TDocStd_Document.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <ViewerTest.hxx>
32 #include <XCAFDoc_ColorTool.hxx>
33 #include <XCAFDoc_DocumentTool.hxx>
34 #include <XCAFDoc_ShapeTool.hxx>
35 #include <XCAFDoc_VisMaterial.hxx>
36 #include <XCAFDoc_VisMaterialTool.hxx>
37 #include <XDEDRAW_Colors.hxx>
38
39 //! Parse XCAFDoc_ColorType enumeration argument.
40 static bool parseXDocColorType (const TCollection_AsciiString& theArg,
41                                 XCAFDoc_ColorType& theType)
42 {
43   TCollection_AsciiString anArgCase (theArg);
44   anArgCase.LowerCase();
45   if (anArgCase == "surf"
46    || anArgCase == "surface"
47    || anArgCase == "s")
48   {
49     theType = XCAFDoc_ColorSurf;
50     return true;
51   }
52   else if (anArgCase == "curve"
53         || anArgCase == "c")
54   {
55     theType = XCAFDoc_ColorCurv;
56     return true;
57   }
58   else if (anArgCase == "gen"
59         || anArgCase == "generic")
60   {
61     theType = XCAFDoc_ColorGen;
62     return true;
63   }
64   return false;
65 }
66
67 //! Print triplet of values.
68 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec3<T>& theVec)
69 {
70   theStream << theVec[0] << " " << theVec[1] << " " << theVec[2];
71   return theStream;
72 }
73
74 //! Print 4 values.
75 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec4<T>& theVec)
76 {
77   theStream << theVec[0] << " " << theVec[1] << " " << theVec[2] << " " << theVec[3];
78   return theStream;
79 }
80
81 //! Convert alpha mode into string.
82 static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
83 {
84   switch (theMode)
85   {
86     case Graphic3d_AlphaMode_Opaque:    return "Opaque";
87     case Graphic3d_AlphaMode_Mask:      return "Mask";
88     case Graphic3d_AlphaMode_Blend:     return "Blend";
89     case Graphic3d_AlphaMode_BlendAuto: return "BlendAuto";
90   }
91   return "";
92 }
93
94 //! Find existing visualization material in the document.
95 static TDF_Label findVisMaterial (const Handle(TDocStd_Document)& theDoc,
96                                   const TCollection_AsciiString& theKey)
97 {
98   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theDoc->Main());
99   TDF_Label aMatLab;
100   TDF_Tool::Label (theDoc->GetData(), theKey, aMatLab);
101   if (!aMatLab.IsNull())
102   {
103     return aMatTool->IsMaterial (aMatLab) ? aMatLab : TDF_Label();
104   }
105
106   TDF_LabelSequence aLabels;
107   aMatTool->GetMaterials (aLabels);
108   for (TDF_LabelSequence::Iterator aLabIter (aLabels); aLabIter.More(); aLabIter.Next())
109   {
110     Handle(TDataStd_Name) aNodeName;
111     if (aLabIter.Value().FindAttribute (TDataStd_Name::GetID(), aNodeName)
112      && aNodeName->Get().IsEqual (theKey))
113     {
114       return aLabIter.Value();
115     }
116   }
117   return TDF_Label();
118 }
119
120 //! Check if image file exists.
121 static bool isImageFileExist (const TCollection_AsciiString& thePath)
122 {
123   const OSD_Path aPath (thePath);
124   if (!OSD_File (aPath).Exists())
125   {
126     std::cout << "Error: file '" << thePath << " not found\n";
127     return false;
128   }
129   return true;
130 }
131
132 //! Parse RGB values coming after specified argument.
133 static bool parseRgbColor (Standard_Integer& theArgIter,
134                            Quantity_Color&   theColor,
135                            Standard_Integer  theNbArgs,
136                            const char**      theArgVec)
137 {
138   Standard_Integer aNbParsed = ViewerTest::ParseColor (theNbArgs - theArgIter - 1,
139                                                        theArgVec + theArgIter + 1,
140                                                        theColor);
141   if (aNbParsed == 0)
142   {
143     std::cout << "Syntax error at '" << theArgVec[theArgIter] << "'\n";
144     return false;
145   }
146   theArgIter += aNbParsed;
147   return true;
148 }
149
150 //! Parse normalized real value within 0..1 range.
151 static bool parseNormalizedReal (const char* theString,
152                                  Standard_ShortReal& theValue)
153 {
154   theValue = (Standard_ShortReal )Draw::Atof (theString);
155   if (theValue < 0.0f || theValue > 1.0f)
156   {
157     std::cerr << "Syntax error at '" << theString << "'\n";
158     return false;
159   }
160   return true;
161 }
162
163 //=======================================================================
164 // Section: Work with colors
165 //=======================================================================
166 static Standard_Integer setColor (Draw_Interpretor& , Standard_Integer argc, const char** argv)
167 {
168   if (argc < 4)
169   {
170     std::cout << "Syntax error: wrong number of arguments\n";
171     return 1;
172   }
173
174   Handle(TDocStd_Document) aDoc;
175   DDocStd::GetDocument (argv[1], aDoc);
176   if (aDoc.IsNull())
177   {
178     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
179     return 1;
180   }
181
182   TDF_Label aLabel;
183   TopoDS_Shape aShape;
184   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
185   if (aLabel.IsNull())
186   {
187     aShape = DBRep::Get (argv[2]);
188     if (aShape.IsNull())
189     {
190       std::cout << "Syntax error: " << argv[2] << " is not a label nor shape\n";
191       return 1;
192     }
193   }
194
195   Quantity_ColorRGBA aColor;
196   bool isColorDefined = false;
197   XCAFDoc_ColorType aColType = XCAFDoc_ColorGen;
198   for (Standard_Integer anArgIter = 3; anArgIter < argc; ++anArgIter)
199   {
200     if (parseXDocColorType (argv[anArgIter], aColType))
201     {
202       //
203     }
204     else if (!isColorDefined)
205     {
206       isColorDefined = true;
207       Standard_Integer aNbParsed = ViewerTest::ParseColor (argc - anArgIter,
208                                                            argv + anArgIter,
209                                                            aColor);
210       if (aNbParsed == 0)
211       {
212         std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
213         return 1;
214       }
215       anArgIter += aNbParsed - 1;
216     }
217     else
218     {
219       std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
220       return 1;
221     }
222   }
223   if (!isColorDefined)
224   {
225     std::cout << "Syntax error: wrong number of arguments\n";
226     return 1;
227   }
228
229   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
230   if (!aLabel.IsNull())
231   {
232     aColorTool->SetColor (aLabel, aColor, aColType);
233   }
234   else if (!aColorTool->SetColor (aShape, aColor, aColType))
235   {
236     std::cout << "Syntax error: " << argv[2] << " is not a label nor shape\n";
237     return 1;
238   }
239   return 0;
240 }
241
242 static Standard_Integer getColor (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
243 {
244   if (argc != 3)
245   {
246     std::cout << "Syntax error: wrong number of arguments\n";
247     return 1;
248   }
249
250   Handle(TDocStd_Document) aDoc;
251   DDocStd::GetDocument (argv[1], aDoc);
252   if (aDoc.IsNull())
253   {
254     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
255     return 1;
256   }
257
258   TDF_Label aLabel;
259   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
260   Handle(XCAFDoc_ColorTool) myColors = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
261   Quantity_ColorRGBA aColor;
262   if (!myColors->GetColor (aLabel, aColor))
263   {
264     return 0;
265   }
266
267   if ((1.0 - aColor.Alpha()) < Precision::Confusion())
268   {
269     di << aColor.GetRGB().StringName (aColor.GetRGB().Name());
270   }
271   else
272   {
273     di << aColor.GetRGB().StringName (aColor.GetRGB().Name()) << " (" << aColor.Alpha() << ")";
274   }
275   return 0;
276 }
277
278 static Standard_Integer getShapeColor (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
279 {
280   if (argc != 3 && argc != 4)
281   {
282     std::cout << "Syntax error: wrong number of arguments\n";
283     return 1;
284   }
285
286   Handle(TDocStd_Document) aDoc;
287   DDocStd::GetDocument (argv[1], aDoc);
288   if (aDoc.IsNull())
289   {
290     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
291     return 1;
292   }
293
294   TDF_Label aLabel;
295   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
296   if (aLabel.IsNull())
297   {
298     std::cout << "Syntax error: '" << argv[2] << "' label is not found in the document\n";
299     return 1;
300   }
301
302   Handle(XCAFDoc_ColorTool) myColors = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
303   XCAFDoc_ColorType aColType = XCAFDoc_ColorGen;
304   if (argc > 3 && !parseXDocColorType (argv[3], aColType))
305   {
306     std::cout << "Syntax error: unknown color type '" << argv[3] << "'\n";
307     return 1;
308   }
309
310   Quantity_ColorRGBA aColor;
311   if (!myColors->GetColor (aLabel, aColType, aColor))
312   {
313     return 0;
314   }
315
316   if ((1.0 - aColor.Alpha()) < Precision::Confusion())
317   {
318     di << aColor.GetRGB().StringName(aColor.GetRGB().Name());
319   }
320   else
321   {
322     di << aColor.GetRGB().StringName(aColor.GetRGB().Name()) << " (" << aColor.Alpha() << ")";
323   }
324
325   return 0;
326 }
327
328 static Standard_Integer getAllColors (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
329 {
330   if (argc != 2)
331   {
332     std::cout << "Syntax error: wrong number of arguments\n";
333     return 1;
334   }
335
336   Handle(TDocStd_Document) aDoc;
337   DDocStd::GetDocument (argv[1], aDoc);
338   if (aDoc.IsNull())
339   {
340     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
341     return 1;
342   }
343
344   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
345   TDF_LabelSequence aLabels;
346   aColorTool->GetColors (aLabels);
347   if (aLabels.Length() >= 1)
348   {
349     for (TDF_LabelSequence::Iterator aLabIter (aLabels); aLabIter.More(); aLabIter.Next())
350     {
351       Quantity_ColorRGBA aColor;
352       if (!aColorTool->GetColor (aLabIter.Value(), aColor))
353       {
354         continue;
355       }
356       if ((1.0 - aColor.Alpha()) < Precision::Confusion())
357       {
358         di << aColor.GetRGB().StringName (aColor.GetRGB().Name());
359       }
360       else
361       {
362         di << aColor.GetRGB().StringName (aColor.GetRGB().Name()) << " (" << aColor.Alpha() << ")";
363       }
364       di << " ";
365     }
366   }
367   return 0;
368 }
369
370 static Standard_Integer addColor (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
371 {
372   if (argc < 3)
373   {
374     std::cout << "Syntax error: wrong number of arguments\n";
375     return 1;
376   }
377
378   Handle(TDocStd_Document) aDoc;
379   DDocStd::GetDocument (argv[1], aDoc);
380   if (aDoc.IsNull())
381   {
382     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
383     return 1;
384   }
385
386   Quantity_ColorRGBA aColRGBA;
387   Standard_Integer aNbParsed = ViewerTest::ParseColor (argc - 2, argv + 2, aColRGBA);
388   if (aNbParsed != argc - 2)
389   {
390     std::cout << "Syntax error at '" << argv[2] << "'\n";
391     return 1;
392   }
393
394   TCollection_AsciiString anEntry;
395   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
396   TDF_Label aLabel = aColorTool->AddColor (aColRGBA);
397   TDF_Tool::Entry (aLabel, anEntry);
398   di << anEntry;
399   return 0;
400 }
401
402 static Standard_Integer removeColor (Draw_Interpretor& , Standard_Integer argc, const char** argv)
403 {
404   if (argc != 3)
405   {
406     std::cout << "Syntax error: wrong number of arguments\n";
407     return 1;
408   }
409
410   Handle(TDocStd_Document) aDoc;
411   TDF_Label aLabel;
412   DDocStd::GetDocument (argv[1], aDoc);
413   if (aDoc.IsNull())
414   {
415     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
416     return 1;
417   }
418   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
419   if (aLabel.IsNull())
420   {
421     std::cout << "Syntax error: " << argv[2] << " label is not found in the document\n";
422     return 1;
423   }
424
425   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
426   aColorTool->RemoveColor (aLabel);
427   return 0;
428 }
429
430 static Standard_Integer findColor (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
431 {
432   if (argc < 3)
433   {
434     std::cout << "Syntax error: wrong number of arguments\n";
435     return 1;
436   }
437
438   Handle(TDocStd_Document) aDoc;
439   DDocStd::GetDocument (argv[1], aDoc);
440   if (aDoc.IsNull())
441   {
442     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
443     return 1;
444   }
445
446   Quantity_ColorRGBA aColRGBA;
447   Standard_Integer aNbParsed = ViewerTest::ParseColor (argc - 2, argv + 2, aColRGBA);
448   if (aNbParsed != argc - 2)
449   {
450     std::cout << "Syntax error at '" << argv[2] << "'\n";
451     return 1;
452   }
453
454   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
455   TCollection_AsciiString anEntry;
456   TDF_Tool::Entry (aColorTool->FindColor (aColRGBA), anEntry);
457   di << anEntry;
458   return 0;
459 }
460
461 static Standard_Integer unsetColor (Draw_Interpretor& , Standard_Integer argc, const char** argv)
462 {
463   if (argc != 4)
464   {
465     std::cout << "Syntax error: wrong number of arguments\n";
466     return 1;
467   }
468
469   Handle(TDocStd_Document) aDoc;
470   DDocStd::GetDocument (argv[1], aDoc);
471   if (aDoc.IsNull())
472   {
473     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
474     return 1;
475   }
476
477   XCAFDoc_ColorType aColType = XCAFDoc_ColorGen;
478   if (!parseXDocColorType (argv[3], aColType))
479   {
480     std::cout << "Syntax error: unknown color type '" << argv[3] << "'\n";
481     return 1;
482   }
483
484   TDF_Label aLabel;
485   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
486   Handle(XCAFDoc_ColorTool) myColors = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
487   if (!aLabel.IsNull())
488   {
489     myColors->UnSetColor (aLabel, aColType);
490     return 0;
491   }
492
493   TopoDS_Shape aShape = DBRep::Get (argv[2]);
494   if (aShape.IsNull())
495   {
496     std::cout << "Syntax error: " << argv[2] << " is not a label nor shape\n";
497     return 1;
498   }
499   myColors->UnSetColor (aShape, aColType);
500   return 0;
501 }
502
503 static Standard_Integer setVisibility (Draw_Interpretor& , Standard_Integer argc, const char** argv)
504 {
505   if (argc != 3 && argc != 4)
506   {
507     std::cout << "Syntax error: wrong number of arguments\n";
508     return 1;
509   }
510
511   Handle(TDocStd_Document) aDoc;
512   TDF_Label aLabel;
513   DDocStd::GetDocument (argv[1], aDoc);
514   if (aDoc.IsNull())
515   {
516     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
517     return 1;
518   }
519
520   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
521   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
522   if (aLabel.IsNull())
523   {
524     // get label by shape
525     TopoDS_Shape aShape = DBRep::Get (argv[2]);
526     if (!aShape.IsNull())
527     {
528       aLabel = aColorTool->ShapeTool()->FindShape (aShape, Standard_True);
529     }
530   }
531   if (aLabel.IsNull())
532   {
533     std::cout << "Syntax error: " << argv[2] << " is not a label not shape\n";
534     return 1;
535   }
536
537   Standard_Boolean isVisible = Standard_False;
538   if (argc == 4)
539   {
540     TCollection_AsciiString aVisArg (argv[3]);
541     if (aVisArg == "1")
542     {
543       isVisible = Standard_True;
544     }
545     else if (aVisArg == "0")
546     {
547       isVisible = Standard_False;
548     }
549     else
550     {
551       std::cout << "Syntax error: unknown argument '" << argv[3] << "'\n";
552       return 1;
553     }
554   }
555   aColorTool->SetVisibility (aLabel, isVisible);
556   return 0;
557 }
558
559 static Standard_Integer getVisibility (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
560 {
561   if (argc != 3)
562   {
563     std::cout << "Syntax error: wrong number of arguments\n";
564     return 1;
565   }
566
567   Handle(TDocStd_Document) aDoc;
568   DDocStd::GetDocument (argv[1], aDoc);
569   if (aDoc.IsNull())
570   {
571     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
572     return 1;
573   }
574
575   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
576   TDF_Label aLabel;
577   TDF_Tool::Label (aDoc->GetData(), argv[2], aLabel);
578   if (aLabel.IsNull())
579   {
580     // get label by shape
581     TopoDS_Shape aShape = DBRep::Get (argv[2]);
582     if (!aShape.IsNull())
583     {
584       aLabel = aColorTool->ShapeTool()->FindShape (aShape, Standard_True);
585     }
586   }
587   if (aLabel.IsNull())
588   {
589     std::cout << "Syntax error: " << argv[2] << " is not a label not shape\n";
590     return 1;
591   }
592
593   di << (aColorTool->IsVisible (aLabel) ? 1 : 0);
594   return 0;
595 }
596
597 static Standard_Integer getStyledVisibility (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
598 {
599   if (argc != 3)
600   {
601     std::cout << "Syntax error: wrong number of arguments\n";
602     return 1;
603   }
604
605   Handle(TDocStd_Document) aDoc;
606   DDocStd::GetDocument (argv[1], aDoc);
607   TopoDS_Shape aShape = DBRep::Get(argv[2]);
608   if (aDoc.IsNull())
609   {
610     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
611     return 1;
612   }
613   if (aShape.IsNull())
614   {
615     std::cout << "Syntax error: " << argv[2] << " is not a shape\n";
616     return 1;
617   }
618
619   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
620   di << (aColorTool->IsInstanceVisible (aShape) ? 1 : 0);
621   return 0;
622 }
623
624 static Standard_Integer getStyledcolor (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
625 {
626   if (argc != 3 && argc != 4)
627   {
628     std::cout << "Syntax error: wrong number of arguments\n";
629     return 1;
630   }
631
632   Handle(TDocStd_Document) aDoc;
633   XCAFDoc_ColorType aColType = XCAFDoc_ColorGen;
634   DDocStd::GetDocument (argv[1], aDoc);
635   TopoDS_Shape aShape = DBRep::Get (argv[2]);
636   if (aDoc.IsNull())
637   {
638     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
639     return 1;
640   }
641   if (aShape.IsNull())
642   {
643     std::cout << "Syntax error: " << argv[2] << " is not a shape\n";
644     return 1;
645   }
646   if (argc > 3 && !parseXDocColorType (argv[3], aColType))
647   {
648     std::cout << "Syntax error: unknown color type '" << argv[3] << "'\n";
649     return 1;
650   }
651
652   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
653   Quantity_ColorRGBA aColor;
654   if (aColorTool->GetInstanceColor (aShape, aColType, aColor))
655   {
656     if ((1.0 - aColor.Alpha()) < Precision::Confusion())
657     {
658       di << aColor.GetRGB().StringName (aColor.GetRGB().Name());
659     }
660     else
661     {
662       di << aColor.GetRGB().StringName (aColor.GetRGB().Name()) << " (" << aColor.Alpha() << ")";
663     }
664   }
665   return 0;
666 }
667
668 static Standard_Integer setStyledcolor (Draw_Interpretor& , Standard_Integer argc, const char** argv)
669 {
670   if (argc < 3)
671   {
672     std::cout << "Syntax error: wrong number of arguments\n";
673     return 1;
674   }
675
676   Handle(TDocStd_Document) aDoc;
677   DDocStd::GetDocument (argv[1], aDoc);
678   if (aDoc.IsNull())
679   {
680     std::cout << "Syntax error: " << argv[1] << " is not a document\n";
681     return 1;
682   }
683
684   TopoDS_Shape aShape = DBRep::Get (argv[2]);
685   if (aShape.IsNull())
686   {
687     std::cout << "Syntax error: " << argv[2] << " is not a shape\n";
688     return 1;
689   }
690
691   XCAFDoc_ColorType aColorType = XCAFDoc_ColorGen;
692   Quantity_ColorRGBA aColRGBA;
693   for (Standard_Integer anArgIter = 3; anArgIter < argc; ++anArgIter)
694   {
695     if (parseXDocColorType (argv[anArgIter], aColorType))
696     {
697       //
698     }
699     else
700     {
701       Standard_Integer aNbParsed = ViewerTest::ParseColor (argc - anArgIter,
702                                                            argv + anArgIter,
703                                                            aColRGBA);
704       if (aNbParsed == 0)
705       {
706         std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
707         return 1;
708       }
709       anArgIter += aNbParsed - 1;
710     }
711   }
712
713   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
714   if (!aColorTool->SetInstanceColor (aShape, aColorType, aColRGBA))
715   {
716     std::cout << "Error: cannot set color for the indicated component\n";
717     return 1;
718   }
719   return 0;
720 }
721
722 // ================================================================
723 // Function : XGetAllVisMaterials
724 // Purpose  :
725 // ================================================================
726 static Standard_Integer XGetAllVisMaterials (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
727 {
728   if (theNbArgs != 2 && theNbArgs != 3)
729   {
730     std::cout << "Syntax error: wrong number of arguments\n";
731     return 1;
732   }
733
734   Handle(TDocStd_Document) aDoc;
735   DDocStd::GetDocument (theArgVec[1], aDoc);
736   if (aDoc.IsNull())
737   {
738     std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n";
739     return 1;
740   }
741
742   bool toPrintNames = true;
743   if (theNbArgs == 3)
744   {
745     TCollection_AsciiString anArgCase (theArgVec[2]);
746     anArgCase.LowerCase();
747     if (anArgCase == "-names")
748     {
749       toPrintNames = true;
750     }
751     else if (anArgCase == "-labels")
752     {
753       toPrintNames = false;
754     }
755   }
756
757   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main());
758   TDF_LabelSequence aLabels;
759   aMatTool->GetMaterials (aLabels);
760   Standard_Integer aMatIndex = 1;
761   for (TDF_LabelSequence::Iterator aLabIter (aLabels); aLabIter.More(); aLabIter.Next(), ++aMatIndex)
762   {
763     const TDF_Label& aMatLab = aLabIter.Value();
764     if (!toPrintNames)
765     {
766       TCollection_AsciiString anEntryId;
767       TDF_Tool::Entry (aMatLab, anEntryId);
768       theDI << anEntryId << " ";
769       continue;
770     }
771
772     Handle(TDataStd_Name) aNodeName;
773     if (aMatLab.FindAttribute (TDataStd_Name::GetID(), aNodeName))
774     {
775       theDI << aNodeName->Get() << " ";
776     }
777     else
778     {
779       TCollection_AsciiString aName = TCollection_AsciiString("<UNNAMED") + aMatIndex + ">";
780       theDI << aName << " ";
781     }
782   }
783   return 0;
784 }
785
786 // ================================================================
787 // Function : XGetVisMaterial
788 // Purpose  :
789 // ================================================================
790 static Standard_Integer XGetVisMaterial (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
791 {
792   if (theNbArgs != 3)
793   {
794     std::cout << "Syntax error: wrong number of arguments\n";
795     return 1;
796   }
797
798   Handle(TDocStd_Document) aDoc;
799   DDocStd::GetDocument (theArgVec[1], aDoc);
800   if (aDoc.IsNull())
801   {
802     std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n";
803     return 1;
804   }
805
806   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main());
807   Handle(XCAFDoc_VisMaterial) aMat;
808   TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]);
809   if (!aMatLab.IsNull())
810   {
811     aMat = aMatTool->GetMaterial (aMatLab);
812   }
813   else
814   {
815     TDF_Label aShapeLab;
816     TDF_Tool::Label (aDoc->GetData(), theArgVec[2], aShapeLab);
817     if (aShapeLab.IsNull())
818     {
819       TopoDS_Shape aShape = DBRep::Get (theArgVec[2]);
820       if (!aShape.IsNull())
821       {
822         aShapeLab = aMatTool->ShapeTool()->FindShape (aShape);
823       }
824     }
825     if (!aShapeLab.IsNull()
826      && !aMatTool->ShapeTool()->IsShape (aShapeLab))
827     {
828       aShapeLab.Nullify();
829     }
830     if (aShapeLab.IsNull())
831     {
832       std::cout << "Syntax error: " << theArgVec[2] << " is not material nor shape\n";
833       return 1;
834     }
835
836     aMat = aMatTool->GetShapeMaterial (aShapeLab);
837   }
838
839   if (aMat.IsNull())
840   {
841     theDI << "EMPTY\n";
842     return 0;
843   }
844
845   TCollection_AsciiString anEntryId;
846   TDF_Tool::Entry (aMat->Label(), anEntryId);
847   theDI << "Label:                  " << anEntryId << "\n";
848
849   Handle(TDataStd_Name) aNodeName;
850   if (aMat->Label().FindAttribute (TDataStd_Name::GetID(), aNodeName))
851   {
852     theDI << "Name:                   " << aNodeName->Get() << "\n";
853   }
854   if (aMat->IsEmpty())
855   {
856     theDI << "EMPTY\n";
857     return 0;
858   }
859   theDI << "AlphaMode:              " << alphaModeToString (aMat->AlphaMode()) << "\n";
860   theDI << "AlphaCutOff:            " << aMat->AlphaCutOff() << "\n";
861   theDI << "IsDoubleSided:          " << aMat->IsDoubleSided() << "\n";
862   if (aMat->HasCommonMaterial())
863   {
864     const XCAFDoc_VisMaterialCommon& aMatCom = aMat->CommonMaterial();
865     theDI << "Common.Ambient:         " << (Graphic3d_Vec3 )aMatCom.AmbientColor << "\n";
866     theDI << "Common.Diffuse:         " << (Graphic3d_Vec3 )aMatCom.DiffuseColor << "\n";
867     if (!aMatCom.DiffuseTexture.IsNull())
868     {
869       theDI << "Common.DiffuseTexture:  " << aMatCom.DiffuseTexture->TextureId() << "\n";
870     }
871     theDI << "Common.Specular:        " << (Graphic3d_Vec3 )aMatCom.SpecularColor << "\n";
872     theDI << "Common.Emissive:        " << (Graphic3d_Vec3 )aMatCom.EmissiveColor << "\n";
873     theDI << "Common.Shininess:       " << aMatCom.Shininess << "\n";
874     theDI << "Common.Transparency:    " << aMatCom.Transparency << "\n";
875   }
876   if (aMat->HasPbrMaterial())
877   {
878     const XCAFDoc_VisMaterialPBR& aMatPbr = aMat->PbrMaterial();
879     theDI << "PBR.BaseColor:          " << (Graphic3d_Vec3 )aMatPbr.BaseColor.GetRGB() << "\n";
880     theDI << "PBR.Transparency:       " << (1.0 - aMatPbr.BaseColor.Alpha()) << "\n";
881     if (!aMatPbr.BaseColorTexture.IsNull())
882     {
883       theDI << "PBR.BaseColorTexture:   " << aMatPbr.BaseColorTexture->TextureId() << "\n";
884     }
885     theDI << "PBR.EmissiveFactor:     " << aMatPbr.EmissiveFactor << "\n";
886     if (!aMatPbr.EmissiveTexture.IsNull())
887     {
888       theDI << "PBR.EmissiveTexture:    " << aMatPbr.EmissiveTexture->TextureId() << "\n";
889     }
890     theDI << "PBR.Metallic:           " << aMatPbr.Metallic << "\n";
891     theDI << "PBR.Roughness:          " << aMatPbr.Roughness << "\n";
892     if (!aMatPbr.MetallicRoughnessTexture.IsNull())
893     {
894       theDI << "PBR.MetallicRoughnessTexture: " << aMatPbr.MetallicRoughnessTexture->TextureId() << "\n";
895     }
896     if (!aMatPbr.OcclusionTexture.IsNull())
897     {
898       theDI << "PBR.OcclusionTexture:   " << aMatPbr.OcclusionTexture->TextureId() << "\n";
899     }
900     if (!aMatPbr.NormalTexture.IsNull())
901     {
902       theDI << "PBR.NormalTexture:      " << aMatPbr.NormalTexture->TextureId() << "\n";
903     }
904   }
905   return 0;
906 }
907
908 // ================================================================
909 // Function : XAddVisMaterial
910 // Purpose  :
911 // ================================================================
912 static Standard_Integer XAddVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec)
913 {
914   if (theNbArgs < 3)
915   {
916     std::cout << "Syntax error: wrong number of arguments\n";
917     return 1;
918   }
919
920   Handle(TDocStd_Document) aDoc;
921   DDocStd::GetDocument (theArgVec[1], aDoc);
922   if (aDoc.IsNull())
923   {
924     std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n";
925     return 1;
926   }
927
928   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main());
929   TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]);
930   if (aMatLab.IsNull())
931   {
932     aMatLab = aMatTool->AddMaterial (theArgVec[2]);
933   }
934
935   Handle(XCAFDoc_VisMaterial) aMat = aMatTool->GetMaterial (aMatLab);
936   XCAFDoc_VisMaterialCommon aMatCom = aMat->CommonMaterial();
937   XCAFDoc_VisMaterialPBR    aMatPbr = aMat->PbrMaterial();
938   Standard_ShortReal aRealValue = 0.0f;
939   for (Standard_Integer anArgIter = 3; anArgIter < theNbArgs; ++anArgIter)
940   {
941     TCollection_AsciiString anArg (theArgVec[anArgIter]);
942     anArg.LowerCase();
943     if ((anArg == "-transparency"
944       || anArg == "-alpha")
945      && anArgIter + 1 < theNbArgs
946      && parseNormalizedReal (theArgVec[anArgIter + 1], aMatCom.Transparency))
947     {
948       ++anArgIter;
949       if (anArg == "-alpha")
950       {
951         aMatCom.Transparency = 1.0f - aMatCom.Transparency;
952       }
953       aMatPbr.BaseColor.SetAlpha (1.0f - aMatCom.Transparency);
954     }
955     else if (anArg == "-alphaMode"
956           && anArgIter + 2 < theNbArgs
957           && parseNormalizedReal (theArgVec[anArgIter + 2], aRealValue))
958     {
959       TCollection_AsciiString aModeStr (theArgVec[anArgIter + 1]);
960       aModeStr.LowerCase();
961       Graphic3d_AlphaMode anAlphaMode = Graphic3d_AlphaMode_Opaque;
962       if (aModeStr == "opaque")
963       {
964         anAlphaMode = Graphic3d_AlphaMode_Opaque;
965       }
966       else if (aModeStr == "mask")
967       {
968         anAlphaMode = Graphic3d_AlphaMode_Mask;
969       }
970       else if (aModeStr == "blend")
971       {
972         anAlphaMode = Graphic3d_AlphaMode_Blend;
973       }
974       else if (aModeStr == "blendauto")
975       {
976         anAlphaMode = Graphic3d_AlphaMode_BlendAuto;
977       }
978       else
979       {
980         std::cerr << "Syntax error at '" << anArg << "'\n";
981         return 1;
982       }
983       aMat->SetAlphaMode (anAlphaMode, aRealValue);
984       anArgIter += 2;
985     }
986     else if (anArg == "-diffuse"
987           || anArg == "-basecolor"
988           || anArg == "-albedo")
989     {
990       Quantity_ColorRGBA aColorRGBA;
991       Standard_Integer aNbParsed = ViewerTest::ParseColor (theNbArgs - anArgIter - 1,
992                                                            theArgVec + anArgIter + 1,
993                                                            aColorRGBA);
994       if (aNbParsed == 0)
995       {
996         std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
997         return 1;
998       }
999       anArgIter += aNbParsed;
1000
1001       if (anArg == "-diffuse")
1002       {
1003         aMatCom.IsDefined = true;
1004         aMatCom.DiffuseColor = aColorRGBA.GetRGB();
1005         if (aNbParsed == 2 || aNbParsed == 4)
1006         {
1007           aMatCom.Transparency = 1.0f - aColorRGBA.Alpha();
1008         }
1009       }
1010       else
1011       {
1012         aMatPbr.IsDefined = true;
1013         if (aNbParsed == 2 || aNbParsed == 4)
1014         {
1015           aMatPbr.BaseColor = aColorRGBA;
1016         }
1017         else
1018         {
1019           aMatPbr.BaseColor.SetRGB (aColorRGBA.GetRGB());
1020         }
1021       }
1022     }
1023     else if (anArg == "-specular"
1024           && parseRgbColor (anArgIter, aMatCom.SpecularColor,
1025                             theNbArgs, theArgVec))
1026     {
1027       aMatCom.IsDefined = true;
1028     }
1029     else if (anArg == "-ambient"
1030           && parseRgbColor (anArgIter, aMatCom.AmbientColor,
1031                             theNbArgs, theArgVec))
1032     {
1033       aMatCom.IsDefined = true;
1034     }
1035     else if (anArg == "-emissive"
1036           && parseRgbColor (anArgIter, aMatCom.EmissiveColor,
1037                             theNbArgs, theArgVec))
1038     {
1039       aMatCom.IsDefined = true;
1040     }
1041     else if (anArg == "-shininess"
1042           && anArgIter + 1 < theNbArgs)
1043     {
1044       aMatCom.IsDefined = true;
1045       aMatCom.Shininess = (float )Draw::Atof (theArgVec[++anArgIter]);
1046       if (aMatCom.Shininess < 0.0f || aMatCom.Shininess > 1.0f)
1047       {
1048         std::cout << "Syntax error at '" << anArg << "'\n";
1049         return 1;
1050       }
1051     }
1052     else if (anArgIter + 1 < theNbArgs
1053           && anArg == "-diffusetexture"
1054           && isImageFileExist (theArgVec[anArgIter + 1]))
1055     {
1056       aMatCom.IsDefined = true;
1057       aMatCom.DiffuseTexture = new Image_Texture (theArgVec[++anArgIter]);
1058     }
1059     else if (anArgIter + 1 < theNbArgs
1060           && anArg == "-basecolortexture"
1061           && isImageFileExist (theArgVec[anArgIter + 1]))
1062     {
1063       aMatPbr.IsDefined = true;
1064       aMatPbr.BaseColorTexture = new Image_Texture (theArgVec[++anArgIter]);
1065     }
1066     else if (anArgIter + 1 < theNbArgs
1067           && anArg == "-emissivetexture"
1068           && isImageFileExist (theArgVec[anArgIter + 1]))
1069     {
1070       aMatPbr.IsDefined = true;
1071       aMatPbr.EmissiveTexture = new Image_Texture (theArgVec[++anArgIter]);
1072     }
1073     else if (anArgIter + 1 < theNbArgs
1074           && anArg == "-metallicroughnesstexture"
1075           && isImageFileExist (theArgVec[anArgIter + 1]))
1076     {
1077       aMatPbr.IsDefined = true;
1078       aMatPbr.MetallicRoughnessTexture = new Image_Texture (theArgVec[++anArgIter]);
1079     }
1080     else if (anArgIter + 1 < theNbArgs
1081           && anArg == "-normaltexture"
1082           && isImageFileExist (theArgVec[anArgIter + 1]))
1083     {
1084       aMatPbr.IsDefined = true;
1085       aMatPbr.NormalTexture = new Image_Texture (theArgVec[++anArgIter]);
1086     }
1087     else if (anArgIter + 1 < theNbArgs
1088           && anArg == "-occlusiontexture"
1089           && isImageFileExist (theArgVec[anArgIter + 1]))
1090     {
1091       aMatPbr.IsDefined = true;
1092       aMatPbr.OcclusionTexture = new Image_Texture (theArgVec[++anArgIter]);
1093     }
1094     else if (anArg == "-emissivefactor"
1095           && anArgIter + 4 < theNbArgs)
1096     {
1097       aMatPbr.IsDefined = true;
1098       aMatPbr.EmissiveFactor.SetValues ((float )Draw::Atof (theArgVec[anArgIter + 1]),
1099                                         (float )Draw::Atof (theArgVec[anArgIter + 2]),
1100                                         (float )Draw::Atof (theArgVec[anArgIter + 3]));
1101       anArgIter += 3;
1102     }
1103     else if (anArg == "-doublesided")
1104     {
1105       aMatPbr.IsDefined = true;
1106       bool isDoubleSided = true;
1107       if (anArgIter + 1 < theNbArgs
1108        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isDoubleSided))
1109       {
1110         ++anArgIter;
1111       }
1112       aMat->SetDoubleSided (isDoubleSided);
1113     }
1114     else if (anArgIter + 1 < theNbArgs
1115           && anArg == "-metallic"
1116           && parseNormalizedReal (theArgVec[anArgIter + 1], aMatPbr.Metallic))
1117     {
1118       ++anArgIter;
1119       aMatPbr.IsDefined = true;
1120     }
1121     else if (anArgIter + 1 < theNbArgs
1122           && anArg == "-roughness"
1123           && parseNormalizedReal (theArgVec[anArgIter + 1], aMatPbr.Roughness))
1124     {
1125       ++anArgIter;
1126       aMatPbr.IsDefined = true;
1127     }
1128     else
1129     {
1130       std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
1131       return 1;
1132     }
1133   }
1134
1135   aMat->SetCommonMaterial (aMatCom);
1136   aMat->SetPbrMaterial (aMatPbr);
1137   return 0;
1138 }
1139
1140 // ================================================================
1141 // Function : XRemoveVisMaterial
1142 // Purpose  :
1143 // ================================================================
1144 static Standard_Integer XRemoveVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec)
1145 {
1146   if (theNbArgs != 3)
1147   {
1148     std::cout << "Syntax error: wrong number of arguments\n";
1149     return 1;
1150   }
1151
1152   Handle(TDocStd_Document) aDoc;
1153   DDocStd::GetDocument (theArgVec[1], aDoc);
1154   if (aDoc.IsNull())
1155   {
1156     std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n";
1157     return 1;
1158   }
1159
1160   TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]);
1161   if (aMatLab.IsNull())
1162   {
1163     std::cout << "Syntax error: " << theArgVec[2] << " is not a material\n";
1164     return 1;
1165   }
1166
1167   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main());
1168   aMatTool->RemoveMaterial (aMatLab);
1169   return 0;
1170 }
1171
1172 // ================================================================
1173 // Function : XSetVisMaterial
1174 // Purpose  :
1175 // ================================================================
1176 static Standard_Integer XSetVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec)
1177 {
1178   if (theNbArgs != 3 && theNbArgs != 4)
1179   {
1180     std::cout << "Syntax error: wrong number of arguments\n";
1181     return 1;
1182   }
1183
1184   Handle(TDocStd_Document) aDoc;
1185   TDF_Label aShapeLab;
1186   DDocStd::GetDocument (theArgVec[1], aDoc);
1187   if (aDoc.IsNull())
1188   {
1189     std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n";
1190     return 1;
1191   }
1192
1193   TDF_Tool::Label (aDoc->GetData(), theArgVec[2], aShapeLab);
1194   Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main());
1195   if (aShapeLab.IsNull())
1196   {
1197     // get label by shape
1198     TopoDS_Shape aShape = DBRep::Get (theArgVec[2]);
1199     if (!aShape.IsNull())
1200     {
1201       aShapeLab = aColorTool->ShapeTool()->FindShape (aShape, Standard_True);
1202     }
1203   }
1204   if (aShapeLab.IsNull())
1205   {
1206     std::cout << "Syntax error: " << theArgVec[2] << " is not a label not shape\n";
1207     return 1;
1208   }
1209
1210   TDF_Label aMatLab;
1211   if (theNbArgs == 4)
1212   {
1213     aMatLab = findVisMaterial (aDoc, theArgVec[3]);
1214     if (aMatLab.IsNull())
1215     {
1216       std::cout << "Syntax error: " << theArgVec[3] << " is not a material\n";
1217       return 1;
1218     }
1219   }
1220
1221   Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main());
1222   aMatTool->SetShapeMaterial (aShapeLab, aMatLab);
1223   return 0;
1224 }
1225
1226 //=======================================================================
1227 //function : InitCommands
1228 //purpose  : 
1229 //=======================================================================
1230
1231 void XDEDRAW_Colors::InitCommands(Draw_Interpretor& di) 
1232 {
1233   static Standard_Boolean initactor = Standard_False;
1234   if (initactor)
1235   {
1236     return;
1237   }
1238   initactor = Standard_True;
1239
1240   //=====================================
1241   // Work with colors
1242   //=====================================  
1243   
1244   Standard_CString g = "XDE color's commands";
1245
1246   di.Add ("XSetColor","Doc {Label|Shape} R G B [alpha] [{generic|surface|curve}=gen]"
1247                       "\t: Set color [R G B] to shape given by Label, "
1248                       "type of color 's' - for surface, 'c' - for curve (default generic)",
1249                    __FILE__, setColor, g);
1250
1251   di.Add ("XGetColor","Doc label"
1252                       "\t: Return color defined on label in colortable",
1253                    __FILE__, getColor, g);
1254
1255   di.Add ("XGetShapeColor","Doc Label {generic|surface|curve}"
1256                            "\t: Returns color defined by label",
1257                    __FILE__, getShapeColor, g);
1258
1259   di.Add ("XGetAllColors","Doc"
1260                           "\t: Print all colors that defined in document",
1261                    __FILE__, getAllColors, g);
1262   
1263   di.Add ("XAddColor","Doc R G B [alpha]"
1264                       "\t: Add color in document to color table",
1265                    __FILE__, addColor, g);
1266   
1267   di.Add ("XRemoveColor","Doc Label"
1268                          "\t: Remove color in document from color table",
1269                    __FILE__, removeColor, g);
1270
1271   di.Add ("XFindColor","Doc R G B [alpha]"
1272                        "\t: Find label where indicated color is situated",
1273                    __FILE__, findColor, g);
1274
1275   di.Add ("XUnsetColor","Doc {Label|Shape} {generic|surface|curve}"
1276                         "\t: Unset color",
1277                    __FILE__, unsetColor, g);
1278   
1279   di.Add ("XSetObjVisibility","Doc {Label|Shape} (0\1) \t: Set the visibility of shape  ",
1280                    __FILE__, setVisibility, g);
1281   
1282   di.Add ("XGetObjVisibility","Doc {Label|Shape} \t: Return the visibility of shape ",
1283                    __FILE__, getVisibility, g);
1284
1285   di.Add ("XGetInstanceVisible","Doc Shape \t: Return the visibility of shape ",
1286                    __FILE__, getStyledVisibility, g);
1287
1288   di.Add ("XGetInstanceColor","Doc Shape [{generic|surface|curve}=gen]"
1289                               "\t: Return the color of component shape",
1290                    __FILE__, getStyledcolor, g);
1291
1292   di.Add ("XSetInstanceColor","Doc Shape R G B [alpha] [{generic|surface|curve}=gen]"
1293                               "\t: sets color for component of shape if SHUO structure exists already",
1294                    __FILE__, setStyledcolor, g);
1295
1296   di.Add ("XGetAllVisMaterials","Doc [{-names|-labels}=-names]"
1297           "\t: Print all visualization materials defined in document",
1298           __FILE__, XGetAllVisMaterials, g);
1299   di.Add ("XGetVisMaterial","Doc {Material|Shape}"
1300           "\t: Print visualization material properties",
1301           __FILE__, XGetVisMaterial, g);
1302   di.Add ("XAddVisMaterial",
1303           "Doc Material"
1304           "\n\t\t: [-transparency 0..1] [-alphaMode {Opaque|Mask|Blend|BlendAuto} CutOffValue]"
1305           "\n\t\t: [-diffuse   RGB] [-diffuseTexture ImagePath]"
1306           "\n\t\t: [-specular  RGB] [-ambient RGB] [-emissive  RGB] [-shininess 0..1]"
1307           "\n\t\t: [-baseColor RGB] [-baseColorTexture ImagePath]"
1308           "\n\t\t: [-emissiveFactor RGB] [-emissiveTexture ImagePath]"
1309           "\n\t\t: [-metallic 0..1] [-roughness 0..1] [-metallicRoughnessTexture ImagePath]"
1310           "\n\t\t: [-occlusionTexture ImagePath] [-normalTexture ImagePath]"
1311           "\n\t\t: [-doubleSided {0|1}]"
1312           "\n\t\t: Add material into Document's material table.",
1313           __FILE__, XAddVisMaterial, g);
1314   di.Add ("XRemoveVisMaterial","Doc Material"
1315           "\t: Remove material in document from material table",
1316           __FILE__, XRemoveVisMaterial, g);
1317   di.Add ("XSetVisMaterial", "Doc Shape Material"
1318           "\t: Set material to shape",
1319           __FILE__, XSetVisMaterial, g);
1320   di.Add ("XUnsetVisMaterial", "Doc Shape"
1321           "\t: Unset material from shape",
1322           __FILE__, XSetVisMaterial, g);
1323 }