1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0025201: Visualization - Implementing soft shadows and ambient occlusion in OCCT ray-tracing core

This commit is contained in:
dbp
2015-04-20 10:15:34 +03:00
committed by bugmaster
parent 283b833c8e
commit 189f85a3fd
41 changed files with 3109 additions and 418 deletions

View File

@@ -12,3 +12,5 @@ ViewerTest_OpenGlCommands.cxx
ViewerTest_ViewerCommands_1.mm
ViewerTest.hxx
ViewerTest.cxx
ViewerTest_CmdParser.hxx
ViewerTest_CmdParser.cxx

View File

@@ -25,6 +25,7 @@
#include <Standard_Stream.hxx>
#include <ViewerTest.hxx>
#include <ViewerTest_CmdParser.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_HArray1OfShape.hxx>
@@ -4804,6 +4805,239 @@ static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a
return 0;
}
//===============================================================================================
//function : VBsdf
//purpose :
//===============================================================================================
static int VBsdf (Draw_Interpretor& theDi,
Standard_Integer theArgsNb,
const char** theArgVec)
{
Handle(V3d_View) aView = ViewerTest::CurrentView();
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
if (aView.IsNull()
|| aViewer.IsNull())
{
std::cerr << "No active viewer!\n";
return 1;
}
ViewerTest_CmdParser aCmd;
aCmd.AddDescription ("Adjusts parameters of material BSDF:");
aCmd.AddOption ("print|echo|p", "Print BSDF");
aCmd.AddOption ("kd", "Weight of the Lambertian BRDF");
aCmd.AddOption ("kr", "Weight of the reflection BRDF");
aCmd.AddOption ("kt", "Weight of the transmission BTDF");
aCmd.AddOption ("ks", "Weight of the glossy Blinn BRDF");
aCmd.AddOption ("le", "Self-emitted radiance");
aCmd.AddOption ("fresnel|f", "Fresnel coefficients; Allowed fresnel formats are: Constant x, Schlick x y z, Dielectric x, Conductor x y");
aCmd.AddOption ("roughness|r", "Roughness of material (Blinn's exponent)");
aCmd.AddOption ("absorpCoeff|af", "Absorption coeff (only for transparent material)");
aCmd.AddOption ("absorpColor|ac", "Absorption color (only for transparent material)");
aCmd.AddOption ("normalize|n", "Normalize BSDF coefficients");
aCmd.Parse (theArgsNb, theArgVec);
if (aCmd.HasOption ("help"))
{
theDi.PrintHelp (theArgVec[0]);
return 0;
}
TCollection_AsciiString aName (aCmd.Arg ("", 0).c_str());
// find object
ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
if (!aMap.IsBound2 (aName) )
{
std::cerr << "Use 'vdisplay' before" << "\n";
return 1;
}
Handle(AIS_InteractiveObject) anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
Graphic3d_BSDF aBSDF = aMaterial.BSDF();
if (aCmd.HasOption ("print"))
{
Graphic3d_Vec4 aFresnel = aBSDF.Fresnel.Serialize();
std::cout << "\n"
<< "Kd: " << aBSDF.Kd.r() << ", " << aBSDF.Kd.g() << ", " << aBSDF.Kd.b() << "\n"
<< "Kr: " << aBSDF.Kr.r() << ", " << aBSDF.Kr.g() << ", " << aBSDF.Kr.b() << "\n"
<< "Kt: " << aBSDF.Kt.r() << ", " << aBSDF.Kt.g() << ", " << aBSDF.Kt.b() << "\n"
<< "Ks: " << aBSDF.Ks.r() << ", " << aBSDF.Ks.g() << ", " << aBSDF.Ks.b() << "\n"
<< "Le: " << aBSDF.Le.r() << ", " << aBSDF.Le.g() << ", " << aBSDF.Le.b() << "\n"
<< "Fresnel: ";
if (aFresnel.x() >= 0.f)
{
std::cout
<< "|Schlick| " << aFresnel.x() << ", " << aFresnel.y() << ", " << aFresnel.z() << "\n";
}
else if (aFresnel.x() >= -1.5f)
{
std::cout
<< "|Constant| " << aFresnel.z() << "\n";
}
else if (aFresnel.x() >= -2.5f)
{
std::cout
<< "|Conductor| " << aFresnel.y() << ", " << aFresnel.z() << "\n";
}
else
{
std::cout
<< "|Dielectric| " << aFresnel.y() << "\n";
}
std::cout
<< "Roughness: " << aBSDF.Roughness << "\n"
<< "Absorption coeff: " << aBSDF.AbsorptionCoeff << "\n"
<< "Absorption color: " << aBSDF.AbsorptionColor.r() << ", "
<< aBSDF.AbsorptionColor.g() << ", "
<< aBSDF.AbsorptionColor.b() << "\n";
return 0;
}
if (aCmd.HasOption ("roughness", 1, Standard_True))
{
aCmd.Arg ("roughness", 0);
aBSDF.Roughness = aCmd.ArgFloat ("roughness");
}
if (aCmd.HasOption ("absorpCoeff", 1, Standard_True))
{
aBSDF.AbsorptionCoeff = aCmd.ArgFloat ("absorpCoeff");
}
if (aCmd.HasOption ("absorpColor", 3, Standard_True))
{
aBSDF.AbsorptionColor = aCmd.ArgVec3f ("absorpColor");
}
if (aCmd.HasOption ("kd", 3))
{
aBSDF.Kd = aCmd.ArgVec3f ("kd");
}
else if (aCmd.HasOption ("kd", 1, Standard_True))
{
aBSDF.Kd = Graphic3d_Vec3 (aCmd.ArgFloat ("kd"));
}
if (aCmd.HasOption ("kr", 3))
{
aBSDF.Kr = aCmd.ArgVec3f ("kr");
}
else if (aCmd.HasOption ("kr", 1, Standard_True))
{
aBSDF.Kr = Graphic3d_Vec3 (aCmd.ArgFloat ("kr"));
}
if (aCmd.HasOption ("kt", 3))
{
aBSDF.Kt = aCmd.ArgVec3f ("kt");
}
else if (aCmd.HasOption ("kt", 1, Standard_True))
{
aBSDF.Kt = Graphic3d_Vec3 (aCmd.ArgFloat ("kt"));
}
if (aCmd.HasOption ("ks", 3))
{
aBSDF.Ks = aCmd.ArgVec3f ("ks");
}
else if (aCmd.HasOption ("ks", 1, Standard_True))
{
aBSDF.Ks = Graphic3d_Vec3 (aCmd.ArgFloat ("ks"));
}
if (aCmd.HasOption ("le", 3))
{
aBSDF.Le = aCmd.ArgVec3f ("le");
}
else if (aCmd.HasOption ("le", 1, Standard_True))
{
aBSDF.Le = Graphic3d_Vec3 (aCmd.ArgFloat ("le"));
}
const std::string aFresnelErrorMessage =
"Error! Wrong Fresnel type. Allowed types are: Constant x, Schlick x y z, Dielectric x, Conductor x y.\n";
if (aCmd.HasOption ("fresnel", 4)) // Schlick: type, x, y ,z
{
std::string aFresnelType = aCmd.Arg ("fresnel", 0);
std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
if (aFresnelType == "schlick")
{
aBSDF.Fresnel = Graphic3d_Fresnel::CreateSchlick (
Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())),
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 3).c_str()))));
}
else
{
std::cout << aFresnelErrorMessage;
}
}
else if (aCmd.HasOption ("fresnel", 3)) // Conductor: type, x, y
{
std::string aFresnelType = aCmd.Arg ("fresnel", 0);
std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
if (aFresnelType == "conductor")
{
aBSDF.Fresnel = Graphic3d_Fresnel::CreateConductor (
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())),
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 2).c_str())));
}
else
{
std::cout << aFresnelErrorMessage;
}
}
else if (aCmd.HasOption ("fresnel", 2)) // Dielectric, Constant: type, x
{
std::string aFresnelType = aCmd.Arg ("fresnel", 0);
std::transform (aFresnelType.begin(), aFresnelType.end(), aFresnelType.begin(), ::tolower);
if (aFresnelType == "dielectric")
{
aBSDF.Fresnel = Graphic3d_Fresnel::CreateDielectric (
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
}
else if (aFresnelType == "constant")
{
aBSDF.Fresnel = Graphic3d_Fresnel::CreateConstant (
static_cast<Standard_ShortReal> (Draw::Atof (aCmd.Arg ("fresnel", 1).c_str())));
}
else
{
std::cout << aFresnelErrorMessage;
}
}
if (aCmd.HasOption ("normalize"))
{
aBSDF.Normalize();
}
aMaterial.SetBSDF (aBSDF);
anIObj->SetMaterial (aMaterial);
aView->Redraw();
return 0;
}
//==============================================================================
//function : VLoadSelection
//purpose : Adds given objects to map of AIS and loads selection primitives for them
@@ -5250,6 +5484,23 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
"\n\t\t: [0|1] - turn off | on auto activation of selection",
__FILE__, VAutoActivateSelection, group);
theCommands.Add("vbsdf", "vbsdf [name] [options]"
"\nAdjusts parameters of material BSDF:"
"\n -help : Shows this message"
"\n -print : Print BSDF"
"\n -kd : Weight of the Lambertian BRDF"
"\n -kr : Weight of the reflection BRDF"
"\n -kt : Weight of the transmission BTDF"
"\n -ks : Weight of the glossy Blinn BRDF"
"\n -le : Self-emitted radiance"
"\n -fresnel : Fresnel coefficients; Allowed fresnel formats are: Constant x,"
"\n Schlick x y z, Dielectric x, Conductor x y"
"\n -roughness : Roughness of material (Blinn's exponent)"
"\n -absorpcoeff : Absorption coefficient (only for transparent material)"
"\n -absorpcolor : Absorption color (only for transparent material)"
"\n -normalize : Normalize BSDF coefficients",
__FILE__, VBsdf, group);
}
//=====================================================================

View File

@@ -0,0 +1,212 @@
// Created on: 2015-03-15
// Created by: Danila ULYANOV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <ViewerTest_CmdParser.hxx>
#include <Draw.hxx>
#include <iostream>
#include <sstream>
#include <string>
//===============================================================================================
//function : ViewerTest_CmdParser
//purpose :
//===============================================================================================
ViewerTest_CmdParser::ViewerTest_CmdParser()
{
ViewerTest_CmdOption aDefaultOption;
myArgumentStorage.push_back (aDefaultOption);
myArgumentLists[""] = 0;
myArgumentLists["help"] = 0;
}
//===============================================================================================
//function : AddOption
//purpose :
//===============================================================================================
void ViewerTest_CmdParser::AddOption (const std::string& theOptionNames, const std::string& theOptionDescription)
{
ViewerTest_CmdOption aNewOption;
// extract option names
std::vector<std::string> aNames;
std::stringstream aStream (theOptionNames);
std::string anItem;
while (std::getline (aStream, anItem, '|'))
{
std::transform (anItem.begin(), anItem.end(), anItem.begin(), ::tolower);
if (!anItem.empty())
{
aNames.push_back (anItem);
}
}
aNewOption.Name = aNames.front();
aNewOption.Description = theOptionDescription;
aNewOption.IsSet = Standard_False;
myArgumentStorage.push_back (aNewOption);
std::vector<std::string>::const_iterator anIt = aNames.begin();
for (; anIt != aNames.end(); ++anIt)
{
myArgumentLists[*anIt] = (Standard_Integer) myArgumentStorage.size() - 1;
}
}
//===============================================================================================
//function : Help
//purpose :
//===============================================================================================
void ViewerTest_CmdParser::Help()
{
std::cout << myDescription << std::endl;
std::vector<ViewerTest_CmdOption>::const_iterator anIt = myArgumentStorage.begin();
for (++anIt; anIt != myArgumentStorage.end(); ++anIt)
{
std::cout << "\n -" << (*anIt).Name << " : " << (*anIt).Description;
}
std::cout << std::endl;
}
//===============================================================================================
//function : Parse
//purpose :
//===============================================================================================
void ViewerTest_CmdParser::Parse (Standard_Integer theArgsNb, const char** theArgVec)
{
Standard_Integer aCurrentOption = 0;
for (Standard_Integer anIter = 1; anIter < theArgsNb; ++anIter)
{
if (theArgVec[anIter][0] == '-')
{
std::string anOptionName (&theArgVec[anIter][1]);
std::transform (anOptionName.begin(), anOptionName.end(), anOptionName.begin(), ::tolower);
std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (anOptionName);
if (aMapIter != myArgumentLists.end())
{
aCurrentOption = aMapIter->second;
myArgumentStorage[aCurrentOption].IsSet = true;
myArgumentStorage[aCurrentOption].Arguments.clear();
}
else
{
std::cerr << "Error: unknown argument '" << theArgVec[anIter] << "'\n";
}
}
else
{
myArgumentStorage[aCurrentOption].Arguments.push_back (theArgVec[anIter]);
}
}
}
//===============================================================================================
//function : HasOption
//purpose :
//===============================================================================================
Standard_Boolean ViewerTest_CmdParser::HasOption (const std::string& theOptionName, Standard_Integer theMandatoryArgsNb /*= 0*/, Standard_Boolean isFatal /*= Standard_False*/)
{
std::string aLowerName = theOptionName;
std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
Standard_Boolean aResult = Standard_False;
std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
if (aMapIter != myArgumentLists.end())
{
Standard_Integer anOption = aMapIter->second;
aResult = myArgumentStorage[anOption].Arguments.size() >= static_cast<size_t> (theMandatoryArgsNb);
if (isFatal && !aResult && myArgumentStorage[anOption].IsSet)
{
std::cerr << "Error: wrong syntax at argument '" << theOptionName << "'\n";
}
aResult &= myArgumentStorage[anOption].IsSet;
}
return aResult;
}
//===============================================================================================
//function : Arg
//purpose :
//===============================================================================================
std::string ViewerTest_CmdParser::Arg (const std::string& theOptionName, Standard_Integer theArgumentIndex)
{
std::string aLowerName = theOptionName;
std::transform (aLowerName.begin(), aLowerName.end(), aLowerName.begin(), ::tolower);
std::map<std::string, Standard_Integer>::iterator aMapIter = myArgumentLists.find (aLowerName);
if (aMapIter != myArgumentLists.end())
{
Standard_Integer anOption = aMapIter->second;
if (myArgumentStorage[anOption].Arguments.size() > static_cast<size_t> (theArgumentIndex))
{
return myArgumentStorage[anOption].Arguments[theArgumentIndex];
}
else
{
std::cerr << "Error: wrong syntax at argument '" << aLowerName << "'\n";
}
}
return "";
}
//===============================================================================================
//function : ArgVec3f
//purpose :
//===============================================================================================
Graphic3d_Vec3 ViewerTest_CmdParser::ArgVec3f (const std::string& theOptionName)
{
return Graphic3d_Vec3 (static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 0).c_str())),
static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 1).c_str())),
static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 2).c_str())));
}
//===============================================================================================
//function : ArgVec3d
//purpose :
//===============================================================================================
Graphic3d_Vec3d ViewerTest_CmdParser::ArgVec3d (const std::string& theOptionName)
{
return Graphic3d_Vec3d ( Draw::Atof (Arg (theOptionName, 0).c_str()),
Draw::Atof (Arg (theOptionName, 1).c_str()),
Draw::Atof (Arg (theOptionName, 2).c_str()));
}
//===============================================================================================
//function : ArgDouble
//purpose :
//===============================================================================================
Standard_Real ViewerTest_CmdParser::ArgDouble (const std::string& theOptionName)
{
return Draw::Atof (Arg (theOptionName, 0).c_str());
}
//===============================================================================================
//function : ArgFloat
//purpose :
//===============================================================================================
Standard_ShortReal ViewerTest_CmdParser::ArgFloat (const std::string& theOptionName)
{
return static_cast<Standard_ShortReal> (Draw::Atof (Arg (theOptionName, 0).c_str()));
}

View File

@@ -0,0 +1,95 @@
// Created on: 2015-03-15
// Created by: Danila ULYANOV
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _ViewerTest_CmdParser_HeaderFile
#define _ViewerTest_CmdParser_HeaderFile
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <Standard.hxx>
#include <Graphic3d_Vec.hxx>
//! Command parser.
class ViewerTest_CmdParser
{
public:
//! Initializes default option.
ViewerTest_CmdParser();
//! Sets description for command.
void AddDescription (const std::string& theDescription)
{
myDescription = theDescription;
}
//! Adds option to available option list. Several names may be provided if separated with '|'.
void AddOption (const std::string& theOptionNames, const std::string& theOptionDescription);
//! Prints help message based on provided command and options descriptions.
void Help();
//! Parses argument list; assignes local arguments to each option.
void Parse (Standard_Integer theArgsNb,
const char** theArgVec);
//! Checks if option was set with given minimal argument number.
//! Prints error message if isFatal flag was set.
Standard_Boolean HasOption (const std::string& theOptionName,
Standard_Integer theMandatoryArgsNb = 0,
Standard_Boolean isFatal = Standard_False);
//! Accesses local argument of option 'theOptionName' with index 'theArgumentIndex'.
std::string Arg (const std::string& theOptionName, Standard_Integer theArgumentIndex);
// Interprets arguments of option 'theOptionName' as float vector.
Graphic3d_Vec3 ArgVec3f (const std::string& theOptionName);
// Interprets arguments of option 'theOptionName' as double vector.
Graphic3d_Vec3d ArgVec3d (const std::string& theOptionName);
// Interprets arguments of option 'theOptionName' as double.
Standard_Real ArgDouble (const std::string& theOptionName);
// Interprets arguments of option 'theOptionName' as float.
Standard_ShortReal ArgFloat (const std::string& theOptionName);
private:
//! Object representing option state.
struct ViewerTest_CmdOption
{
ViewerTest_CmdOption() : IsSet (Standard_False) {}
std::string Name;
std::string Description;
Standard_Boolean IsSet;
std::vector<std::string> Arguments;
};
//! Description of command.
std::string myDescription;
//! Map from all possible option names to option object indexes in myArgumentStorage.
std::map<std::string, Standard_Integer> myArgumentLists;
//! Container which stores option objects.
std::vector<ViewerTest_CmdOption> myArgumentStorage;
};
#endif // _ViewerTest_CmdParser_HeaderFile

View File

@@ -7502,58 +7502,64 @@ static int VLight (Draw_Interpretor& theDi,
{
case V3d_AMBIENT:
{
theDi << " Type: Ambient\n";
theDi << " Type: Ambient\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
break;
}
case V3d_DIRECTIONAL:
{
Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
theDi << " Type: Directional\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Directional\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightDir.IsNull())
{
aLightDir->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
}
break;
}
case V3d_POSITIONAL:
{
Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
theDi << " Type: Positional\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Positional\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Smoothness: " << aLight->Smoothness() << "\n";
if (!aLightPos.IsNull())
{
aLightPos->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightPos->Attenuation (anAtten[0], anAtten[1]);
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
}
break;
}
case V3d_SPOT:
{
Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
theDi << " Type: Spot\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
theDi << " Type: Spot\n";
theDi << " Intensity: " << aLight->Intensity() << "\n";
theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
if (!aLightSpot.IsNull())
{
aLightSpot->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
aLightSpot->Attenuation (anAtten[0], anAtten[1]);
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
theDi << " Exponent: " << aLightSpot->Concentration() << "\n";
}
break;
}
default:
{
theDi << " Type: UNKNOWN\n";
theDi << " Type: UNKNOWN\n";
break;
}
}
@@ -7785,6 +7791,56 @@ static int VLight (Draw_Interpretor& theDi,
return 1;
}
}
else if (anArgCase.IsEqual ("SM")
|| anArgCase.IsEqual ("SMOOTHNESS"))
{
if (++anArgIt >= theArgsNb)
{
std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
return 1;
}
Standard_Real aSmoothness = Atof (theArgVec[anArgIt]);
if (fabs (aSmoothness) < Precision::Confusion())
{
aLightCurr->SetIntensity (1.f);
}
else if (fabs (aLightCurr->Smoothness()) < Precision::Confusion())
{
aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
}
else
{
Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
}
if (!aLightPos.IsNull())
{
aLightPos->SetSmoothRadius (aSmoothness);
}
else if (!aLightDir.IsNull())
{
aLightDir->SetSmoothAngle (aSmoothness);
}
}
else if (anArgCase.IsEqual ("INT")
|| anArgCase.IsEqual ("INTENSITY"))
{
if (++anArgIt >= theArgsNb)
{
std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
return 1;
}
Standard_Real aIntensity = Atof (theArgVec[anArgIt]);
if (!aLightCurr.IsNull())
{
aLightCurr->SetIntensity (aIntensity);
}
}
else if (anArgCase.IsEqual ("ANG")
|| anArgCase.IsEqual ("ANGLE"))
{
@@ -7975,11 +8031,12 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
}
theDI << "\n";
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
{
@@ -8066,7 +8123,9 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
}
const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
if (aDepth < 1 || aDepth > 10)
// We allow RaytracingDepth be more than 10 in case of GI enabled
if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
{
std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
return 1;
@@ -8142,6 +8201,42 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
}
aParams.IsTransparentShadowEnabled = toEnable;
}
else if (aFlag == "-gi")
{
if (toPrint)
{
theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
continue;
}
Standard_Boolean toEnable = Standard_True;
if (++anArgIter < theArgNb
&& !parseOnOff (theArgVec[anArgIter], toEnable))
{
--anArgIter;
}
aParams.IsGlobalIlluminationEnabled = toEnable;
if (!toEnable)
{
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
}
}
else if (aFlag == "-env")
{
if (toPrint)
{
theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
continue;
}
Standard_Boolean toEnable = Standard_True;
if (++anArgIter < theArgNb
&& !parseOnOff (theArgVec[anArgIter], toEnable))
{
--anArgIter;
}
aParams.UseEnvironmentMapBackground = toEnable;
}
else if (aFlag == "-shademodel"
|| aFlag == "-shadingmodel"
|| aFlag == "-shading")
@@ -8200,9 +8295,56 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
return 1;
}
}
return 0;
}
//=======================================================================
//function : VProgressiveMode
//purpose :
//=======================================================================
#if defined(_WIN32)
static Standard_Integer VProgressiveMode (Draw_Interpretor& /*theDI*/,
Standard_Integer /*theNbArgs*/,
const char** /*theArgs*/)
{
Handle(V3d_View) aView = ViewerTest::CurrentView();
if (aView.IsNull())
{
std::cerr << "Error: no active viewer!\n";
return 1;
}
std::cout << "Press Enter or Escape key to exit progressive rendering mode" << std::endl;
for (;;)
{
aView->Redraw();
Standard_Boolean toExit = Standard_False;
MSG aMsg;
while (PeekMessage (&aMsg, NULL, NULL, NULL, PM_REMOVE))
{
if (aMsg.message == WM_KEYDOWN && (aMsg.wParam == 0x0d || aMsg.wParam == 0x1b))
{
toExit = Standard_True;
}
TranslateMessage (&aMsg);
DispatchMessage (&aMsg);
}
if (toExit)
{
break;
}
}
return 0;
}
#endif
//=======================================================================
//function : VFrustumCulling
//purpose : enables/disables view volume's culling.
@@ -8817,6 +8959,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n {dir}ection X Y Z (for directional light or for spotlight)"
"\n color colorName"
"\n {head}light 0|1"
"\n {sm}oothness value"
"\n {int}ensity value"
"\n {constAtten}uation value"
"\n {linearAtten}uation value"
"\n angle angleDeg"
@@ -8827,7 +8971,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
__FILE__, VLight, group);
theCommands.Add("vraytrace",
"vraytrace [0|1]"
"\n\t\t: Turn on/off raytracing renderer."
"\n\t\t: Turns on/off ray-tracing renderer."
"\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
"\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
__FILE__, VRenderParams, group);
@@ -8840,6 +8984,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n '-reflections on|off' Enables/disables specular reflections"
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
"\n '-gleam on|off' Enables/disables transparency shadow effects"
"\n '-gi on|off' Enables/disables global illumination effects"
"\n '-env on|off' Enables/disables environment map background"
"\n '-shadingModel model' Controls shading model from enumeration"
"\n color, flat, gouraud, phong"
"\n Unlike vcaps, these parameters dramatically change visual properties."
@@ -8861,4 +9007,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"vxrotate",
__FILE__,VXRotate,group);
#if defined(_WIN32)
theCommands.Add("vprogressive",
"vprogressive",
__FILE__, VProgressiveMode, group);
#endif
}