1 // Created on: 2012-04-09
2 // Created by: Sergey ANIKIN
3 // Copyright (c) 2012-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 #include <ViewerTest.hxx>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <Draw.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <Image_AlienPixMap.hxx>
22 #include <Message.hxx>
23 #include <OSD_File.hxx>
24 #include <OSD_FileSystem.hxx>
25 #include <V3d_View.hxx>
26 #include <V3d_Viewer.hxx>
27
28 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
29
30 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
31
32 //==============================================================================
33 //function : VImmediateFront
34 //purpose :
35 //==============================================================================
36
VImmediateFront(Draw_Interpretor &,Standard_Integer theArgNb,const char ** theArgVec)37 static int VImmediateFront (Draw_Interpretor& ,
38 Standard_Integer theArgNb,
39 const char** theArgVec)
40 {
41 // get the context
42 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
43 if (aContextAIS.IsNull())
44 {
45 Message::SendFail ("Error: no active viewer");
46 return 1;
47 }
48
49 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
50 if (aDriver.IsNull())
51 {
52 Message::SendFail ("Error: graphic driver not available.");
53 return 1;
54 }
55
56 if (theArgNb < 2)
57 {
58 Message::SendFail ("Syntax error: wrong number of arguments.");
59 return 1;
60 }
61
62 ViewerTest::CurrentView()->View()->SetImmediateModeDrawToFront (atoi(theArgVec[1]) != 0);
63
64 return 0;
65 }
66
67 //! Search the info from the key.
searchInfo(const TColStd_IndexedDataMapOfStringString & theDict,const TCollection_AsciiString & theKey)68 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
69 const TCollection_AsciiString& theKey)
70 {
71 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
72 {
73 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
74 {
75 return anIter.Value();
76 }
77 }
78 return TCollection_AsciiString();
79 }
80
81 //==============================================================================
82 //function : VGlInfo
83 //purpose :
84 //==============================================================================
85
VGlInfo(Draw_Interpretor & theDI,Standard_Integer theArgNb,const char ** theArgVec)86 static int VGlInfo (Draw_Interpretor& theDI,
87 Standard_Integer theArgNb,
88 const char** theArgVec)
89 {
90 // get the active view
91 Handle(V3d_View) aView = ViewerTest::CurrentView();
92 if (aView.IsNull())
93 {
94 Message::SendFail ("No active viewer");
95 return 1;
96 }
97
98 Graphic3d_DiagnosticInfo anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
99 Standard_Integer aLineWidth = 80;
100 NCollection_Sequence<TCollection_AsciiString> aKeys;
101 TColStd_IndexedDataMapOfStringString aDict;
102 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
103 {
104 TCollection_AsciiString aName (theArgVec[anArgIter]);
105 aName.LowerCase();
106 TCollection_AsciiString aValue;
107 if (aName == "-short")
108 {
109 anInfoLevel = Graphic3d_DiagnosticInfo_Short;
110 }
111 else if (aName == "-basic")
112 {
113 anInfoLevel = Graphic3d_DiagnosticInfo_Basic;
114 }
115 else if (aName == "-complete"
116 || aName == "-full")
117 {
118 anInfoLevel = Graphic3d_DiagnosticInfo_Complete;
119 }
120 else if (anArgIter + 1 < theArgNb
121 && (aName == "-maxwidth"
122 || aName == "-maxlinewidth"
123 || aName == "-linewidth"))
124 {
125 aLineWidth = Draw::Atoi (theArgVec[++anArgIter]);
126 if (aLineWidth < 0)
127 {
128 aLineWidth = IntegerLast();
129 }
130 }
131 else if (aName.Search ("vendor") != -1)
132 {
133 aKeys.Append ("GLvendor");
134 }
135 else if (aName.Search ("renderer") != -1)
136 {
137 aKeys.Append ("GLdevice");
138 }
139 else if (aName.Search ("shading_language_version") != -1
140 || aName.Search ("glsl") != -1)
141 {
142 aKeys.Append ("GLSLversion");
143 }
144 else if (aName.Search ("version") != -1)
145 {
146 aKeys.Append ("GLversion");
147 }
148 else if (aName.Search ("extensions") != -1)
149 {
150 aKeys.Append ("GLextensions");
151 }
152 else if (aName.Search ("extensions") != -1)
153 {
154 aKeys.Append ("GLextensions");
155 }
156 else
157 {
158 Message::SendFail() << "Syntax error: unknown key '" << aName << "'";
159 return 1;
160 }
161 }
162
163 if (aKeys.IsEmpty())
164 {
165 aView->DiagnosticInformation (aDict, anInfoLevel);
166 TCollection_AsciiString aText;
167 for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aDict); aValueIter.More(); aValueIter.Next())
168 {
169 if (!aText.IsEmpty())
170 {
171 aText += "\n";
172 }
173 if ((aValueIter.Key().Length() + aValueIter.Value().Length() + 4) <= aLineWidth)
174 {
175 aText += TCollection_AsciiString(" ") + aValueIter.Key() + ": " + aValueIter.Value();
176 continue;
177 }
178
179 // split into lines
180 aText += TCollection_AsciiString(" ") + aValueIter.Key() + ":";
181 TCollection_AsciiString aSubList;
182 for (Standard_Integer aTokenIter = 1;; ++aTokenIter)
183 {
184 TCollection_AsciiString aToken = aValueIter.Value().Token (" ", aTokenIter);
185 if (aToken.IsEmpty())
186 {
187 break;
188 }
189
190 if (!aSubList.IsEmpty()
191 && (aSubList.Length() + aToken.Length() + 5) > aLineWidth)
192 {
193 aText += TCollection_AsciiString("\n ") + aSubList;
194 aSubList = aToken;
195 }
196 else
197 {
198 if (!aSubList.IsEmpty())
199 {
200 aSubList += " ";
201 }
202 aSubList += aToken;
203 }
204 }
205 if (!aSubList.IsEmpty())
206 {
207 aText += TCollection_AsciiString("\n ") + aSubList;
208 }
209 }
210
211 theDI << "OpenGL info:\n"
212 << aText;
213 return 0;
214 }
215
216 aView->DiagnosticInformation (aDict, Graphic3d_DiagnosticInfo_Complete);
217 for (NCollection_Sequence<TCollection_AsciiString>::Iterator aKeyIter (aKeys); aKeyIter.More(); aKeyIter.Next())
218 {
219 TCollection_AsciiString aValue = searchInfo (aDict, aKeyIter.Value());
220 if (aKeys.Length() > 1)
221 {
222 theDI << "{" << aValue << "} ";
223 }
224 else
225 {
226 theDI << aValue;
227 }
228 }
229
230 return 0;
231 }
232
233
234 //! Parse shader type argument.
parseShaderTypeArg(Graphic3d_TypeOfShaderObject & theType,const TCollection_AsciiString & theArg)235 static bool parseShaderTypeArg (Graphic3d_TypeOfShaderObject& theType,
236 const TCollection_AsciiString& theArg)
237 {
238 if (theArg == "-vertex"
239 || theArg == "-vert")
240 {
241 theType = Graphic3d_TOS_VERTEX;
242 }
243 else if (theArg == "-tessevaluation"
244 || theArg == "-tesseval"
245 || theArg == "-evaluation"
246 || theArg == "-eval")
247 {
248 theType = Graphic3d_TOS_TESS_EVALUATION;
249 }
250 else if (theArg == "-tesscontrol"
251 || theArg == "-tessctrl"
252 || theArg == "-control"
253 || theArg == "-ctrl")
254 {
255 theType = Graphic3d_TOS_TESS_CONTROL;
256 }
257 else if (theArg == "-geometry"
258 || theArg == "-geom")
259 {
260 theType = Graphic3d_TOS_GEOMETRY;
261 }
262 else if (theArg == "-fragment"
263 || theArg == "-frag")
264 {
265 theType = Graphic3d_TOS_FRAGMENT;
266 }
267 else if (theArg == "-compute"
268 || theArg == "-comp")
269 {
270 theType = Graphic3d_TOS_COMPUTE;
271 }
272 else
273 {
274 return false;
275 }
276 return true;
277 }
278
279 //==============================================================================
280 //function : VShaderProg
281 //purpose : Sets the pair of vertex and fragment shaders for the object
282 //==============================================================================
VShaderProg(Draw_Interpretor &,Standard_Integer theArgNb,const char ** theArgVec)283 static Standard_Integer VShaderProg (Draw_Interpretor& ,
284 Standard_Integer theArgNb,
285 const char** theArgVec)
286 {
287 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
288 if (aCtx.IsNull())
289 {
290 Message::SendFail ("Error: no active viewer");
291 return 1;
292 }
293 else if (theArgNb < 2)
294 {
295 Message::SendFail ("Syntax error: lack of arguments");
296 return 1;
297 }
298
299 bool isExplicitShaderType = false;
300 Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
301 NCollection_Sequence<Handle(AIS_InteractiveObject)> aPrsList;
302 Graphic3d_GroupAspect aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
303 bool isSetGroupAspect = false;
304 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
305 {
306 TCollection_AsciiString anArg (theArgVec[anArgIter]);
307 anArg.LowerCase();
308 Graphic3d_TypeOfShaderObject aShaderTypeArg = Graphic3d_TypeOfShaderObject(-1);
309 if (!aProgram.IsNull()
310 && anArg == "-uniform"
311 && anArgIter + 2 < theArgNb)
312 {
313 TCollection_AsciiString aName = theArgVec[++anArgIter];
314 aProgram->PushVariableFloat (aName, float (Draw::Atof (theArgVec[++anArgIter])));
315 }
316 else if (!aProgram.IsNull()
317 && aProgram->ShaderObjects().IsEmpty()
318 && (anArg == "-off"
319 || anArg == "off"))
320 {
321 aProgram.Nullify();
322 }
323 else if (!aProgram.IsNull()
324 && aProgram->ShaderObjects().IsEmpty()
325 && (anArg == "-phong"
326 || anArg == "phong"))
327 {
328 const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder();
329 if (aShadersRoot.IsEmpty())
330 {
331 Message::SendFail("Error: both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
332 "At least one should be defined to load Phong program.");
333 return 1;
334 }
335
336 const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs";
337 const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs";
338 if (!aSrcVert.IsEmpty()
339 && !OSD_File (aSrcVert).Exists())
340 {
341 Message::SendFail ("Error: PhongShading.vs is not found");
342 return 1;
343 }
344 if (!aSrcFrag.IsEmpty()
345 && !OSD_File (aSrcFrag).Exists())
346 {
347 Message::SendFail ("Error: PhongShading.fs is not found");
348 return 1;
349 }
350
351 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
352 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
353 }
354 else if (aPrsList.IsEmpty()
355 && anArg == "*")
356 {
357 //
358 }
359 else if (!isSetGroupAspect
360 && anArgIter + 1 < theArgNb
361 && (anArg == "-primtype"
362 || anArg == "-primitivetype"
363 || anArg == "-groupaspect"
364 || anArg == "-aspecttype"
365 || anArg == "-aspect"))
366 {
367 isSetGroupAspect = true;
368 TCollection_AsciiString aPrimTypeStr (theArgVec[++anArgIter]);
369 aPrimTypeStr.LowerCase();
370 if (aPrimTypeStr == "line")
371 {
372 aGroupAspect = Graphic3d_ASPECT_LINE;
373 }
374 else if (aPrimTypeStr == "tris"
375 || aPrimTypeStr == "triangles"
376 || aPrimTypeStr == "fill"
377 || aPrimTypeStr == "fillarea"
378 || aPrimTypeStr == "shading"
379 || aPrimTypeStr == "shade")
380 {
381 aGroupAspect = Graphic3d_ASPECT_FILL_AREA;
382 }
383 else if (aPrimTypeStr == "text")
384 {
385 aGroupAspect = Graphic3d_ASPECT_TEXT;
386 }
387 else if (aPrimTypeStr == "marker"
388 || aPrimTypeStr == "point"
389 || aPrimTypeStr == "pnt")
390 {
391 aGroupAspect = Graphic3d_ASPECT_MARKER;
392 }
393 else
394 {
395 Message::SendFail() << "Syntax error at '" << aPrimTypeStr << "'";
396 return 1;
397 }
398 }
399 else if (anArgIter + 1 < theArgNb
400 && !aProgram.IsNull()
401 && aProgram->Header().IsEmpty()
402 && (anArg == "-version"
403 || anArg == "-glslversion"
404 || anArg == "-header"
405 || anArg == "-glslheader"))
406 {
407 TCollection_AsciiString aHeader (theArgVec[++anArgIter]);
408 if (aHeader.IsIntegerValue())
409 {
410 aHeader = TCollection_AsciiString ("#version ") + aHeader;
411 }
412 aProgram->SetHeader (aHeader);
413 }
414 else if (!anArg.StartsWith ("-")
415 && GetMapOfAIS().IsBound2 (theArgVec[anArgIter]))
416 {
417 Handle(AIS_InteractiveObject) anIO = GetMapOfAIS().Find2 (theArgVec[anArgIter]);
418 if (anIO.IsNull())
419 {
420 Message::SendFail() << "Syntax error: " << theArgVec[anArgIter] << " is not an AIS object";
421 return 1;
422 }
423 aPrsList.Append (anIO);
424 }
425 else if (!aProgram.IsNull()
426 && ((anArgIter + 1 < theArgNb && parseShaderTypeArg (aShaderTypeArg, anArg))
427 || (!isExplicitShaderType && aProgram->ShaderObjects().Size() < 2)))
428 {
429 TCollection_AsciiString aShaderPath (theArgVec[anArgIter]);
430 if (aShaderTypeArg != Graphic3d_TypeOfShaderObject(-1))
431 {
432 aShaderPath = (theArgVec[++anArgIter]);
433 isExplicitShaderType = true;
434 }
435
436 const bool isSrcFile = OSD_File (aShaderPath).Exists();
437 Handle(Graphic3d_ShaderObject) aShader = isSrcFile
438 ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aShaderPath)
439 : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aShaderPath);
440 const TCollection_AsciiString& aShaderSrc = aShader->Source();
441
442 const bool hasVertPos = aShaderSrc.Search ("gl_Position") != -1;
443 const bool hasFragColor = aShaderSrc.Search ("occSetFragColor") != -1
444 || aShaderSrc.Search ("occFragColor") != -1
445 || aShaderSrc.Search ("gl_FragColor") != -1
446 || aShaderSrc.Search ("gl_FragData") != -1;
447 Graphic3d_TypeOfShaderObject aShaderType = aShaderTypeArg;
448 if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
449 {
450 if (hasVertPos
451 && !hasFragColor)
452 {
453 aShaderType = Graphic3d_TOS_VERTEX;
454 }
455 if (hasFragColor
456 && !hasVertPos)
457 {
458 aShaderType = Graphic3d_TOS_FRAGMENT;
459 }
460 }
461 if (aShaderType == Graphic3d_TypeOfShaderObject(-1))
462 {
463 Message::SendFail() << "Error: non-existing or invalid shader source";
464 return 1;
465 }
466
467 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aShaderType, aShaderSrc));
468 }
469 else
470 {
471 Message::SendFail() << "Syntax error at '" << anArg << "'";
472 return 1;
473 }
474 }
475
476 if (!aProgram.IsNull()
477 && ViewerTest::CurrentView()->RenderingParams().TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
478 {
479 aProgram->SetNbFragmentOutputs (2);
480 aProgram->SetOitOutput (Graphic3d_RTM_BLEND_OIT);
481 }
482
483 ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName aGlobalPrsIter (GetMapOfAIS());
484 NCollection_Sequence<Handle(AIS_InteractiveObject)>::Iterator aPrsIter (aPrsList);
485 const bool isGlobalList = aPrsList.IsEmpty();
486 for (;;)
487 {
488 Handle(AIS_InteractiveObject) anIO;
489 if (isGlobalList)
490 {
491 if (!aGlobalPrsIter.More())
492 {
493 break;
494 }
495 anIO = aGlobalPrsIter.Key1();
496 aGlobalPrsIter.Next();
497 if (anIO.IsNull())
498 {
499 continue;
500 }
501 }
502 else
503 {
504 if (!aPrsIter.More())
505 {
506 break;
507 }
508 anIO = aPrsIter.Value();
509 aPrsIter.Next();
510 }
511
512 if (anIO->Attributes()->SetShaderProgram (aProgram, aGroupAspect, true))
513 {
514 aCtx->Redisplay (anIO, Standard_False);
515 }
516 else
517 {
518 anIO->SynchronizeAspects();
519 }
520 }
521
522 aCtx->UpdateCurrentViewer();
523 return 0;
524 }
525
526 //! Print triplet of values.
operator <<(S & theStream,const NCollection_Vec3<T> & theVec)527 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec3<T>& theVec)
528 {
529 theStream << theVec[0] << " " << theVec[1] << " " << theVec[2];
530 return theStream;
531 }
532
533 //! Print 4 values.
operator <<(S & theStream,const NCollection_Vec4<T> & theVec)534 template<class S, class T> static S& operator<< (S& theStream, const NCollection_Vec4<T>& theVec)
535 {
536 theStream << theVec[0] << " " << theVec[1] << " " << theVec[2] << " " << theVec[3];
537 return theStream;
538 }
539
540 //! Print fresnel model.
fresnelModelString(const Graphic3d_FresnelModel theModel)541 static const char* fresnelModelString (const Graphic3d_FresnelModel theModel)
542 {
543 switch (theModel)
544 {
545 case Graphic3d_FM_SCHLICK: return "SCHLICK";
546 case Graphic3d_FM_CONSTANT: return "CONSTANT";
547 case Graphic3d_FM_CONDUCTOR: return "CONDUCTOR";
548 case Graphic3d_FM_DIELECTRIC: return "DIELECTRIC";
549 }
550 return "N/A";
551 }
552
553 //! Create a colored rectangle SVG element.
formatSvgColoredRect(const Quantity_Color & theColor)554 static TCollection_AsciiString formatSvgColoredRect (const Quantity_Color& theColor)
555 {
556 return TCollection_AsciiString()
557 + "<svg width='20px' height='20px'><rect width='20px' height='20px' fill='" + Quantity_Color::ColorToHex (theColor) + "' /></svg>";
558 }
559
560 //==============================================================================
561 //function : VListMaterials
562 //purpose :
563 //==============================================================================
VListMaterials(Draw_Interpretor & theDI,Standard_Integer theArgNb,const char ** theArgVec)564 static Standard_Integer VListMaterials (Draw_Interpretor& theDI,
565 Standard_Integer theArgNb,
566 const char** theArgVec)
567 {
568 TCollection_AsciiString aDumpFile;
569 NCollection_Sequence<Graphic3d_NameOfMaterial> aMatList;
570 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
571 {
572 TCollection_AsciiString anArg (theArgVec[anArgIter]);
573 anArg.LowerCase();
574 Graphic3d_NameOfMaterial aMat = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter]);
575 if (aMat != Graphic3d_NameOfMaterial_DEFAULT)
576 {
577 aMatList.Append (aMat);
578 }
579 else if (anArg == "*")
580 {
581 for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NameOfMaterial_DEFAULT; ++aMatIter)
582 {
583 aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
584 }
585 }
586 else if (aDumpFile.IsEmpty()
587 && (anArg.EndsWith (".obj")
588 || anArg.EndsWith (".mtl")
589 || anArg.EndsWith (".htm")
590 || anArg.EndsWith (".html")))
591 {
592 aDumpFile = theArgVec[anArgIter];
593 }
594 else
595 {
596 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
597 return 1;
598 }
599 }
600 if (aMatList.IsEmpty())
601 {
602 if (aDumpFile.IsEmpty())
603 {
604 for (Standard_Integer aMatIter = 1; aMatIter <= Graphic3d_MaterialAspect::NumberOfMaterials(); ++aMatIter)
605 {
606 theDI << Graphic3d_MaterialAspect::MaterialName (aMatIter) << " ";
607 }
608 return 0;
609 }
610
611 for (Standard_Integer aMatIter = 0; aMatIter < (Standard_Integer )Graphic3d_NameOfMaterial_DEFAULT; ++aMatIter)
612 {
613 aMatList.Append ((Graphic3d_NameOfMaterial )aMatIter);
614 }
615 }
616
617 // geometry for dumping
618 const Graphic3d_Vec3 aBoxVerts[8] =
619 {
620 Graphic3d_Vec3( 1, -1, -1),
621 Graphic3d_Vec3( 1, -1, 1),
622 Graphic3d_Vec3(-1, -1, 1),
623 Graphic3d_Vec3(-1, -1, -1),
624 Graphic3d_Vec3( 1, 1, -1),
625 Graphic3d_Vec3( 1, 1, 1),
626 Graphic3d_Vec3(-1, 1, 1),
627 Graphic3d_Vec3(-1, 1, -1)
628 };
629
630 const Graphic3d_Vec4i aBoxQuads[6] =
631 {
632 Graphic3d_Vec4i (1, 2, 3, 4),
633 Graphic3d_Vec4i (5, 8, 7, 6),
634 Graphic3d_Vec4i (1, 5, 6, 2),
635 Graphic3d_Vec4i (2, 6, 7, 3),
636 Graphic3d_Vec4i (3, 7, 8, 4),
637 Graphic3d_Vec4i (5, 1, 4, 8)
638 };
639
640 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
641 opencascade::std::shared_ptr<std::ostream> aMatFile, anObjFile, aHtmlFile;
642 if (aDumpFile.EndsWith (".obj")
643 || aDumpFile.EndsWith (".mtl"))
644 {
645 const TCollection_AsciiString aMatFilePath = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "mtl";
646 const TCollection_AsciiString anObjFilePath = aDumpFile.SubString (1, aDumpFile.Length() - 3) + "obj";
647
648 aMatFile = aFileSystem->OpenOStream (aMatFilePath, std::ios::out | std::ios::binary);
649 if (aMatFile.get() == NULL)
650 {
651 Message::SendFail ("Error: unable creating material file");
652 return 0;
653 }
654 if (!aDumpFile.EndsWith (".mtl"))
655 {
656 anObjFile = aFileSystem->OpenOStream (anObjFilePath, std::ios::out | std::ios::binary);
657 if (anObjFile.get() == NULL)
658 {
659 Message::SendFail ("Error: unable creating OBJ file");
660 return 0;
661 }
662
663 TCollection_AsciiString anMtlName, aFolder;
664 OSD_Path::FolderAndFileFromPath (aMatFilePath, aFolder, anMtlName);
665 *anObjFile << "mtllib " << anMtlName << "\n";
666 }
667 }
668 else if (aDumpFile.EndsWith (".htm")
669 || aDumpFile.EndsWith (".html"))
670 {
671 aHtmlFile = aFileSystem->OpenOStream (aDumpFile, std::ios::out | std::ios::binary);
672 if (aHtmlFile.get() == NULL)
673 {
674 Message::SendFail ("Error: unable creating HTML file");
675 return 0;
676 }
677 *aHtmlFile << "<html>\n"
678 "<head><title>OCCT Material table</title></head>\n"
679 "<body>\n"
680 "<table border='1'><tbody>\n"
681 "<tr>\n"
682 "<th rowspan='2'><div title='Material name.\n"
683 "See also Graphic3d_NameOfMaterial enumeration'>"
684 "Name</div></th>\n"
685 "<th rowspan='2'><div title='Material type: PHYSIC or ASPECT.\n"
686 "ASPECT material does not define final colors, it is taken from Internal Color instead.\n"
687 "See also Graphic3d_TypeOfMaterial enumeration'>"
688 "Type</div></th>\n"
689 "<th rowspan='2'>Transparency</th>\n"
690 "<th colspan='5'><div title='PBR Metallic-Roughness'>"
691 "PBR Metallic-Roughness</div></th>\n"
692 "<th colspan='5'><div title='Common material definition for Phong shading model'>"
693 "Common (Blinn-Phong)</div></th>\n"
694 "<th colspan='10'><div title='BSDF (Bidirectional Scattering Distribution Function).\n"
695 "Used for physically-based rendering (in path tracing engine).\n"
696 "BSDF is represented as weighted mixture of basic BRDFs/BTDFs (Bidirectional Reflectance (Transmittance) Distribution Functions).\n"
697 "See also Graphic3d_BSDF structure.'>"
698 "BSDF (Bidirectional Scattering Distribution Function)</div></th>\n"
699 "</tr>\n"
700 "<tr>\n"
701 "<th>Color</th>\n"
702 "<th>Metallic</th>\n"
703 "<th>Roughness</th>\n"
704 "<th>Emission</th>\n"
705 "<th><div title='Index of refraction'>"
706 "IOR</div></th>\n"
707 "<th>Ambient</th>\n"
708 "<th>Diffuse</th>\n"
709 "<th>Specular</th>\n"
710 "<th>Emissive</th>\n"
711 "<th>Shiness</th>\n"
712 "<th><div title='Weight of coat specular/glossy BRDF'>"
713 "Kc</div></th>\n"
714 "<th><div title='Weight of base diffuse BRDF'>"
715 "Kd</div></th>\n"
716 "<th><div title='Weight of base specular/glossy BRDF'>"
717 "Ks</div></th>\n"
718 "<th><div title='Weight of base specular/glossy BTDF'>"
719 "Kt</div></th>\n"
720 "<th><div title='Radiance emitted by the surface'>"
721 "Le</div></th>\n"
722 "<th><div title='Volume scattering color/density'>"
723 "Absorption</div></th>\n"
724 "<th><div title='Parameters of Fresnel reflectance of coat layer'>"
725 "FresnelCoat</div></th>\n"
726 "<th><div title='Parameters of Fresnel reflectance of base layer'>"
727 "FresnelBase</div></th>\n"
728 "<th>Refraction Index</th>\n"
729 "</tr>\n";
730 }
731 else if (!aDumpFile.IsEmpty())
732 {
733 Message::SendFail ("Syntax error: unknown output file format");
734 return 1;
735 }
736
737 Standard_Integer aMatIndex = 0, anX = 0, anY = 0;
738 for (NCollection_Sequence<Graphic3d_NameOfMaterial>::Iterator aMatIter (aMatList); aMatIter.More(); aMatIter.Next(), ++aMatIndex)
739 {
740 Graphic3d_MaterialAspect aMat (aMatIter.Value());
741 const TCollection_AsciiString aMatName = aMat.StringName();
742 const Graphic3d_Vec3 anAmbient = (Graphic3d_Vec3 )aMat.AmbientColor();
743 const Graphic3d_Vec3 aDiffuse = (Graphic3d_Vec3 )aMat.DiffuseColor();
744 const Graphic3d_Vec3 aSpecular = (Graphic3d_Vec3 )aMat.SpecularColor();
745 const Graphic3d_Vec3 anEmission = (Graphic3d_Vec3 )aMat.EmissiveColor();
746 const Standard_Real aShiness = aMat.Shininess() * 1000.0;
747 if (aMatFile.get() != NULL)
748 {
749 *aMatFile << "newmtl " << aMatName << "\n";
750 *aMatFile << "Ka " << Quantity_Color::Convert_LinearRGB_To_sRGB (anAmbient) << "\n";
751 *aMatFile << "Kd " << Quantity_Color::Convert_LinearRGB_To_sRGB (aDiffuse) << "\n";
752 *aMatFile << "Ks " << Quantity_Color::Convert_LinearRGB_To_sRGB (aSpecular) << "\n";
753 *aMatFile << "Ns " << aShiness << "\n";
754 if (aMat.Transparency() >= 0.0001)
755 {
756 *aMatFile << "Tr " << aMat.Transparency() << "\n";
757 }
758 *aMatFile << "\n";
759 }
760 else if (aHtmlFile.get() != NULL)
761 {
762 *aHtmlFile << "<tr>\n";
763 *aHtmlFile << "<td>" << aMat.StringName() << "</td>\n";
764 *aHtmlFile << "<td>" << (aMat.MaterialType() == Graphic3d_MATERIAL_PHYSIC ? "PHYSIC" : "ASPECT") << "</td>\n";
765 *aHtmlFile << "<td>" << aMat.Transparency() << "</td>\n";
766 *aHtmlFile << "<td>" << formatSvgColoredRect (aMat.PBRMaterial().Color().GetRGB()) << (Graphic3d_Vec3 )aMat.PBRMaterial().Color().GetRGB() << "</td>\n";
767 *aHtmlFile << "<td>" << aMat.PBRMaterial().Metallic() << "</td>\n";
768 *aHtmlFile << "<td>" << aMat.PBRMaterial().NormalizedRoughness() << "</td>\n";
769 *aHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aMat.PBRMaterial().Emission())) << aMat.PBRMaterial().Emission() << "</td>\n";
770 *aHtmlFile << "<td>" << aMat.PBRMaterial().IOR() << "</td>\n";
771 *aHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anAmbient)) << anAmbient << "</td>\n";
772 *aHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aDiffuse)) << aDiffuse << "</td>\n";
773 *aHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (aSpecular)) << aSpecular << "</td>\n";
774 *aHtmlFile << "<td>" << formatSvgColoredRect (Quantity_Color (anEmission)) << anEmission << "</td>\n";
775 *aHtmlFile << "<td>" << aMat.Shininess() << "</td>\n";
776 *aHtmlFile << "<td>" << aMat.BSDF().Kc << "</td>\n";
777 *aHtmlFile << "<td>" << aMat.BSDF().Kd << "</td>\n";
778 *aHtmlFile << "<td>" << aMat.BSDF().Ks << "</td>\n";
779 *aHtmlFile << "<td>" << aMat.BSDF().Kt << "</td>\n";
780 *aHtmlFile << "<td>" << aMat.BSDF().Le << "</td>\n";
781 *aHtmlFile << "<td>" << aMat.BSDF().Absorption << "</td>\n";
782 *aHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "</td>\n";
783 *aHtmlFile << "<td>" << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "</td>\n";
784 *aHtmlFile << "<td>" << aMat.RefractionIndex() << "</td>\n";
785 *aHtmlFile << "</tr>\n";
786 }
787 else
788 {
789 theDI << aMat.StringName() << "\n";
790 theDI << " Transparency: " << aMat.Transparency() << "\n";
791 theDI << " PBR.BaseColor: " << (Graphic3d_Vec3 )aMat.PBRMaterial().Color().GetRGB() << "\n";
792 theDI << " PBR.Metallic: " << aMat.PBRMaterial().Metallic() << "\n";
793 theDI << " PBR.Roughness: " << aMat.PBRMaterial().NormalizedRoughness() << "\n";
794 theDI << " PBR.Emission: " << aMat.PBRMaterial().Emission() << "\n";
795 theDI << " PBR.IOR: " << aMat.PBRMaterial().IOR() << "\n";
796 theDI << " Common.Ambient: " << anAmbient << "\n";
797 theDI << " Common.Diffuse: " << aDiffuse << "\n";
798 theDI << " Common.Specular: " << aSpecular << "\n";
799 theDI << " Common.Emissive: " << anEmission << "\n";
800 theDI << " Common.Shiness: " << aMat.Shininess() << "\n";
801 theDI << " BSDF.Kc: " << aMat.BSDF().Kc << "\n";
802 theDI << " BSDF.Kd: " << aMat.BSDF().Kd << "\n";
803 theDI << " BSDF.Ks: " << aMat.BSDF().Ks << "\n";
804 theDI << " BSDF.Kt: " << aMat.BSDF().Kt << "\n";
805 theDI << " BSDF.Le: " << aMat.BSDF().Le << "\n";
806 theDI << " BSDF.Absorption: " << aMat.BSDF().Absorption << "\n";
807 theDI << " BSDF.FresnelCoat: " << fresnelModelString (aMat.BSDF().FresnelCoat.FresnelType()) << "\n";
808 theDI << " BSDF.FresnelBase: " << fresnelModelString (aMat.BSDF().FresnelBase.FresnelType()) << "\n";
809 theDI << " RefractionIndex: " << aMat.RefractionIndex() << "\n";
810 }
811
812 if (anObjFile.get() != NULL)
813 {
814 *anObjFile << "g " << aMatName << "\n";
815 *anObjFile << "usemtl " << aMatName << "\n";
816 for (Standard_Integer aVertIter = 0; aVertIter < 8; ++aVertIter)
817 {
818 *anObjFile << "v " << (aBoxVerts[aVertIter] + Graphic3d_Vec3 (3.0f * anX, -3.0f * anY, 0.0f)) << "\n";
819 }
820 *anObjFile << "s off\n";
821 for (Standard_Integer aFaceIter = 0; aFaceIter < 6; ++aFaceIter)
822 {
823 *anObjFile << "f " << (aBoxQuads[aFaceIter] + Graphic3d_Vec4i (8 * aMatIndex)) << "\n";
824 }
825 *anObjFile << "\n";
826 if (++anX > 5)
827 {
828 anX = 0;
829 ++anY;
830 }
831 }
832 }
833
834 if (aHtmlFile.get() != NULL)
835 {
836 *aHtmlFile << "</tbody></table>\n</body>\n</html>\n";
837 }
838 return 0;
839 }
840
841 //==============================================================================
842 //function : VListColors
843 //purpose :
844 //==============================================================================
VListColors(Draw_Interpretor & theDI,Standard_Integer theArgNb,const char ** theArgVec)845 static Standard_Integer VListColors (Draw_Interpretor& theDI,
846 Standard_Integer theArgNb,
847 const char** theArgVec)
848 {
849 TCollection_AsciiString aDumpFile;
850 NCollection_Sequence<Quantity_NameOfColor> aColList;
851 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
852 {
853 TCollection_AsciiString anArg (theArgVec[anArgIter]);
854 anArg.LowerCase();
855 Quantity_NameOfColor aName;
856 if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aName))
857 {
858 aColList.Append (aName);
859 }
860 else if (anArg == "*")
861 {
862 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
863 {
864 aColList.Append ((Quantity_NameOfColor )aColIter);
865 }
866 }
867 else if (aDumpFile.IsEmpty()
868 && (anArg.EndsWith (".htm")
869 || anArg.EndsWith (".html")))
870 {
871 aDumpFile = theArgVec[anArgIter];
872 }
873 else
874 {
875 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
876 return 1;
877 }
878 }
879 if (aColList.IsEmpty())
880 {
881 if (aDumpFile.IsEmpty())
882 {
883 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
884 {
885 theDI << Quantity_Color::StringName (Quantity_NameOfColor (aColIter)) << " ";
886 }
887 return 0;
888 }
889
890 for (Standard_Integer aColIter = 0; aColIter <= (Standard_Integer )Quantity_NOC_WHITE; ++aColIter)
891 {
892 aColList.Append ((Quantity_NameOfColor )aColIter);
893 }
894 }
895
896 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
897 opencascade::std::shared_ptr<std::ostream> aHtmlFile;
898 TCollection_AsciiString aFileNameBase, aFolder;
899 if (aDumpFile.EndsWith (".htm")
900 || aDumpFile.EndsWith (".html"))
901 {
902 OSD_Path::FolderAndFileFromPath (aDumpFile, aFolder, aFileNameBase);
903 aFileNameBase = aFileNameBase.SubString (1, aFileNameBase.Length() - (aDumpFile.EndsWith (".htm") ? 4 : 5));
904 }
905 else if (!aDumpFile.IsEmpty())
906 {
907 Message::SendFail ("Syntax error: unknown output file format");
908 return 1;
909 }
910
911 Standard_Integer aMaxNameLen = 1;
912 for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next())
913 {
914 aMaxNameLen = Max (aMaxNameLen, TCollection_AsciiString (Quantity_Color::StringName (aColIter.Value())).Length());
915 }
916
917 V3d_ImageDumpOptions anImgParams;
918 anImgParams.Width = 60;
919 anImgParams.Height = 30;
920 anImgParams.BufferType = Graphic3d_BT_RGB;
921 anImgParams.StereoOptions = V3d_SDO_MONO;
922 anImgParams.ToAdjustAspect = Standard_True;
923 Handle(V3d_View) aView;
924 if (!aDumpFile.IsEmpty())
925 {
926 ViewerTest::ViewerInit (0, 0, anImgParams.Width, anImgParams.Height, "TmpDriver/TmpViewer/TmpView");
927 aView = ViewerTest::CurrentView();
928 aView->SetImmediateUpdate (false);
929 aView->SetBgGradientStyle (Aspect_GradientFillMethod_None, false);
930 }
931
932 if (!aDumpFile.IsEmpty())
933 {
934 aHtmlFile = aFileSystem->OpenOStream (aDumpFile, std::ios::out | std::ios::binary);
935 if (aHtmlFile.get() == NULL)
936 {
937 Message::SendFail ("Error: unable creating HTML file");
938 return 0;
939 }
940 *aHtmlFile << "<html>\n"
941 << "<head><title>OCCT Color table</title></head>\n"
942 << "<body>\n"
943 << "<table border='1'><tbody>\n"
944 << "<tr>\n"
945 << "<th>HTML</th>\n"
946 << "<th>OCCT</th>\n"
947 << "<th>Color name</th>\n"
948 << "<th>sRGB hex</th>\n"
949 << "<th>sRGB dec</th>\n"
950 << "<th>RGB linear</th>\n"
951 << "</tr>\n";
952 }
953
954 Image_AlienPixMap anImg;
955 Standard_Integer aColIndex = 0;
956 for (NCollection_Sequence<Quantity_NameOfColor>::Iterator aColIter (aColList); aColIter.More(); aColIter.Next(), ++aColIndex)
957 {
958 Quantity_Color aCol (aColIter.Value());
959 const TCollection_AsciiString aColName = Quantity_Color::StringName (aColIter.Value());
960 const TCollection_AsciiString anSRgbHex = Quantity_Color::ColorToHex (aCol);
961 const Graphic3d_Vec3i anSRgbInt ((Graphic3d_Vec3 )aCol * 255.0f);
962 if (aHtmlFile.get() != NULL)
963 {
964 const TCollection_AsciiString anImgPath = aFileNameBase + "_" + aColName + ".png";
965 if (!aView.IsNull())
966 {
967 aView->SetImmediateUpdate (false);
968 aView->SetBackgroundColor (aCol);
969 if (!aView->ToPixMap (anImg, anImgParams)
970 || !anImg.Save (aFolder + anImgPath))
971 {
972 theDI << "Error: image dump failed\n";
973 return 0;
974 }
975 }
976
977 *aHtmlFile << "<tr>\n";
978 *aHtmlFile << "<td style='background-color:" << anSRgbHex << "'><pre> </pre></td>\n";
979 *aHtmlFile << "<td><img src='" << (!aView.IsNull() ? anImgPath : "") << "'></img></td>\n";
980 *aHtmlFile << "<td style='text-align:left'>" << aColName << "</td>\n";
981 *aHtmlFile << "<td style='text-align:left'><pre>" << anSRgbHex << "</pre></td>\n";
982 *aHtmlFile << "<td style='text-align:left'>(" << anSRgbInt.r() << " " << anSRgbInt.g() << " " << anSRgbInt.b() << ")</td>\n";
983 *aHtmlFile << "<td style='text-align:left'>(" << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << ")</td>\n";
984 *aHtmlFile << "</tr>\n";
985 }
986 else
987 {
988 TCollection_AsciiString aColNameLong (aColName);
989 aColNameLong.RightJustify (aMaxNameLen, ' ');
990 theDI << aColNameLong << " [" << anSRgbHex << "]: " << aCol.Red() << " " << aCol.Green() << " " << aCol.Blue() << "\n";
991 }
992 }
993
994 if (!aView.IsNull())
995 {
996 ViewerTest::RemoveView (aView);
997 }
998
999 if (aHtmlFile.get() != NULL)
1000 {
1001 *aHtmlFile << "</tbody></table>\n</body>\n</html>\n";
1002 }
1003 return 0;
1004 }
1005
1006 //==============================================================================
1007 //function : envlutWriteToFile
1008 //purpose :
1009 //==============================================================================
envLutWriteToFile(Standard_ShortReal theValue)1010 static std::string envLutWriteToFile (Standard_ShortReal theValue)
1011 {
1012 std::stringstream aStream;
1013 aStream << theValue;
1014 if (aStream.str().length() == 1)
1015 {
1016 aStream << '.';
1017 }
1018 aStream << 'f';
1019 return aStream.str();
1020 }
1021
1022 //==============================================================================
1023 //function : VGenEnvLUT
1024 //purpose :
1025 //==============================================================================
VGenEnvLUT(Draw_Interpretor &,Standard_Integer theArgNb,const char ** theArgVec)1026 static Standard_Integer VGenEnvLUT (Draw_Interpretor&,
1027 Standard_Integer theArgNb,
1028 const char** theArgVec)
1029 {
1030 Standard_Integer aTableSize = -1;
1031 Standard_Integer aNbSamples = -1;
1032 TCollection_AsciiString aFilePath = Graphic3d_TextureRoot::TexturesFolder() + "/Textures_EnvLUT.pxx";
1033
1034 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1035 {
1036 TCollection_AsciiString anArg(theArgVec[anArgIter]);
1037 anArg.LowerCase();
1038
1039 if (anArg == "-size"
1040 || anArg == "-s")
1041 {
1042 if (anArgIter + 1 >= theArgNb)
1043 {
1044 Message::SendFail ("Syntax error: size of PBR environment look up table is undefined");
1045 return 1;
1046 }
1047
1048 aTableSize = Draw::Atoi(theArgVec[++anArgIter]);
1049
1050 if (aTableSize < 16)
1051 {
1052 Message::SendFail ("Error: size of PBR environment look up table must be greater or equal 16");
1053 return 1;
1054 }
1055 }
1056 else if (anArg == "-nbsamples"
1057 || anArg == "-samples")
1058 {
1059 if (anArgIter + 1 >= theArgNb)
1060 {
1061 Message::SendFail ("Syntax error: number of samples to generate PBR environment look up table is undefined");
1062 return 1;
1063 }
1064
1065 aNbSamples = Draw::Atoi(theArgVec[++anArgIter]);
1066
1067 if (aNbSamples < 1)
1068 {
1069 Message::SendFail ("Syntax error: number of samples to generate PBR environment look up table must be greater than 1");
1070 return 1;
1071 }
1072 }
1073 else
1074 {
1075 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1076 return 1;
1077 }
1078 }
1079
1080 if (aTableSize < 0)
1081 {
1082 aTableSize = 128;
1083 }
1084
1085 if (aNbSamples < 0)
1086 {
1087 aNbSamples = 1024;
1088 }
1089
1090 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
1091 opencascade::std::shared_ptr<std::ostream> aFile = aFileSystem->OpenOStream (aFilePath, std::ios::out | std::ios::trunc);
1092
1093 if (aFile.get() == NULL || !aFile->good())
1094 {
1095 Message::SendFail() << "Error: unable to write to " << aFilePath;
1096 return 1;
1097 }
1098
1099 *aFile << "//this file has been generated by vgenenvlut draw command\n";
1100 *aFile << "static unsigned int Textures_EnvLUTSize = " << aTableSize << ";\n\n";
1101 *aFile << "static float Textures_EnvLUT[] =\n";
1102 *aFile << "{\n";
1103
1104 Handle(Image_PixMap) aPixMap = new Image_PixMap();
1105 aPixMap->InitZero (Image_Format_RGF, aTableSize, aTableSize);
1106 Graphic3d_PBRMaterial::GenerateEnvLUT (aPixMap, aNbSamples);
1107
1108 const Standard_Integer aNumbersInRow = 5;
1109 Standard_Integer aCounter = 0;
1110
1111 for (int y = 0; y < aTableSize - 1; ++y)
1112 {
1113 aCounter = 0;
1114 for (int x = 0; x < aTableSize; ++x)
1115 {
1116 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(aTableSize - 1 - y, x).x()) << ",";
1117 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(aTableSize - 1 - y, x).y()) << ",";
1118 if (++aCounter % aNumbersInRow == 0)
1119 {
1120 *aFile << "\n";
1121 }
1122 else if (x != aTableSize - 1)
1123 {
1124 *aFile << " ";
1125 }
1126 }
1127 *aFile << "\n";
1128 if (aTableSize % aNumbersInRow != 0)
1129 {
1130 *aFile << "\n";
1131 }
1132 }
1133
1134 aCounter = 0;
1135 for (int x = 0; x < aTableSize - 1; ++x)
1136 {
1137 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, x).x()) << ",";
1138 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, x).y()) << ",";
1139 if (++aCounter % aNumbersInRow == 0)
1140 {
1141 *aFile << "\n";
1142 }
1143 else
1144 {
1145 *aFile << " ";
1146 }
1147 }
1148
1149 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, aTableSize - 1).x()) << ",";
1150 *aFile << envLutWriteToFile (aPixMap->Value<Graphic3d_Vec3>(0, aTableSize - 1).y()) << "\n";
1151
1152 *aFile << "};";
1153
1154 return 0;
1155 }
1156
1157 //=======================================================================
1158 //function : OpenGlCommands
1159 //purpose :
1160 //=======================================================================
1161
OpenGlCommands(Draw_Interpretor & theCommands)1162 void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands)
1163 {
1164 const char* aGroup ="Commands for low-level TKOpenGl features";
1165
1166 theCommands.Add("vimmediatefront",
1167 "vimmediatefront : render immediate mode to front buffer or to back buffer",
1168 __FILE__, VImmediateFront, aGroup);
1169 theCommands.Add("vglinfo",
1170 "vglinfo [-short|-basic|-complete] [-lineWidth Value=80]"
1171 "\n\t\t: [GL_VENDOR] [GL_RENDERER] [GL_VERSION]"
1172 "\n\t\t: [GL_SHADING_LANGUAGE_VERSION] [GL_EXTENSIONS]"
1173 "\n\t\t: print OpenGL info."
1174 "\n\t\t: -lineWidth split values longer than specified value into multiple lines;"
1175 "\n\t\t: -1 disables splitting.",
1176 __FILE__, VGlInfo, aGroup);
1177 theCommands.Add("vshader",
1178 "vshader name -vert VertexShader -frag FragmentShader [-geom GeometryShader]"
1179 "\n\t\t: [-off] [-phong] [-aspect {shading|line|point|text}=shading]"
1180 "\n\t\t: [-header VersionHeader]"
1181 "\n\t\t: [-tessControl TessControlShader -tesseval TessEvaluationShader]"
1182 "\n\t\t: [-uniform Name FloatValue]"
1183 "\n\t\t: Assign custom GLSL program to presentation aspects.",
1184 __FILE__, VShaderProg, aGroup);
1185 theCommands.Add("vshaderprog", "Alias for vshader", __FILE__, VShaderProg, aGroup);
1186 theCommands.Add("vlistmaterials",
1187 "vlistmaterials [*] [MaterialName1 [MaterialName2 [...]]] [dump.obj|dump.html]"
1188 "\n\t\t: Without arguments, command prints the list of standard materials."
1189 "\n\t\t: Otherwise, properties of specified materials will be printed"
1190 "\n\t\t: or dumped into specified file."
1191 "\n\t\t: * can be used to refer to complete list of standard materials.",
1192 __FILE__, VListMaterials, aGroup);
1193 theCommands.Add("vlistcolors",
1194 "vlistcolors [*] [ColorName1 [ColorName2 [...]]] [dump.html]"
1195 "\n\t\t: Without arguments, command prints the list of standard colors."
1196 "\n\t\t: Otherwise, properties of specified colors will be printed"
1197 "\n\t\t: or dumped into specified file."
1198 "\n\t\t: * can be used to refer to complete list of standard colors.",
1199 __FILE__, VListColors, aGroup);
1200 theCommands.Add("vgenenvlut",
1201 "vgenenvlut [-size size = 128] [-nbsamples nbsamples = 1024]"
1202 "\n\t\t: Generates PBR environment look up table."
1203 "\n\t\t: Saves it as C++ source file which is expected to be included in code."
1204 "\n\t\t: The path where result will be located is 'Graphic3d_TextureRoot::TexturesFolder()'."
1205 "\n\t\t: -size size of one side of resulted square table"
1206 "\n\t\t: -nbsamples number of samples used in Monte-Carlo integration",
1207 __FILE__, VGenEnvLUT, aGroup);
1208 }
1209