Factored viewer args parsing for into common place

Started refactoring how we parse arguments for sample viewer
applications into a common place.  This will make it easier
to keep args consistent between applications.
This commit is contained in:
George ElKoura 2019-04-02 18:29:00 -07:00
parent 40855edf12
commit 61f5ceabde
10 changed files with 453 additions and 119 deletions

View File

@ -29,23 +29,28 @@ set(EXAMPLES_COMMON_SHADER_FILES
)
set(EXAMPLES_COMMON_SOURCE_FILES
argOptions.cpp
font_image.cpp
hdr_reader.cpp
hud.cpp
objAnim.cpp
patchColors.cpp
viewerArgsUtils.cpp
)
set(EXAMPLES_COMMON_HEADER_FILES
argOptions.h
font_image.h
hdr_reader.h
hud.h
objAnim.h
patchColors.h
shaderCache.h
shapeDesc.h
simple_math.h
stb_image_write.h
stopwatch.h
viewerArgsUtils.h
)
if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))

View File

@ -0,0 +1,97 @@
//
// Copyright 2019 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../common/argOptions.h"
static int
parseIntArg(const char* argString, int dfltValue = 0) {
char *argEndptr;
int argValue = strtol(argString, &argEndptr, 10);
if (*argEndptr != 0) {
printf("Warning: non-integer option parameter '%s' ignored\n",
argString);
argValue = dfltValue;
}
return argValue;
}
ArgOptions::ArgOptions()
: _adaptive(false)
, _fullscreen(false)
, _level(2)
, _objsAreAnim(false)
, _axis(true)
, _repeatCount(0)
, _defaultScheme(kCatmark)
{
}
void
ArgOptions::Parse(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
if (strstr(argv[i], ".obj")) {
_objFiles.push_back(argv[i]);
} else if (!strcmp(argv[i], "-a")) {
_adaptive = true;
} else if (!strcmp(argv[i], "-u")) {
_adaptive = false;
} else if (!strcmp(argv[i], "-l")) {
if (++i < argc) _level = parseIntArg(argv[i], 2);
} else if (!strcmp(argv[i], "-c")) {
if (++i < argc) _repeatCount = parseIntArg(argv[i], 0);
} else if (!strcmp(argv[i], "-f")) {
_fullscreen = true;
} else if (!strcmp(argv[i], "-axis")) {
_axis = false;
} else if (!strcmp(argv[i], "-anim")) {
_objsAreAnim = true;
} else if (!strcmp(argv[i], "-bilinear")) {
_defaultScheme = kBilinear;
} else if (!strcmp(argv[i], "-catmark")) {
_defaultScheme = kCatmark;
} else if (!strcmp(argv[i], "-loop")) {
_defaultScheme = kLoop;
} else {
_remainingArgs.push_back(argv[i]);
}
}
}
void
ArgOptions::PrintUnrecognizedArgWarning(const char *arg) const
{
printf("Warning: unrecognized argument '%s' ignored\n", arg);
}
void
ArgOptions::PrintUnrecognizedArgsWarnings() const
{
for(size_t i = 0; i < _remainingArgs.size(); ++i) {
PrintUnrecognizedArgWarning(_remainingArgs[i]);
}
}

View File

@ -0,0 +1,95 @@
//
// Copyright 2019 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef COMMON_ARGS_H
#define COMMON_ARGS_H
#include "../../regression/common/shape_utils.h"
#include <vector>
class ArgOptions
{
public:
ArgOptions();
// Uses argc and argv to initialize the members of this object.
void Parse(int argc, char **argv);
// Prints out unrecognized argument warnings for each argument left in
// remainingArgs
void PrintUnrecognizedArgsWarnings() const;
// Print unrecognized warning for arg
void PrintUnrecognizedArgWarning(const char *arg) const;
// Accessors to parsed arguments
//
bool GetAdaptive() const { return _adaptive; }
bool GetFullScreen() const { return _fullscreen; }
int GetLevel() const { return _level; }
bool GetObjsAreAnim() const { return _objsAreAnim; }
bool GetAxis() const { return _axis; }
int GetRepeatCount() const { return _repeatCount; }
Scheme GetDefaultScheme() const { return _defaultScheme; }
const std::vector<const char *> GetObjFiles() const { return _objFiles; }
const std::vector<const char *> GetRemainingArgs() const {
return _remainingArgs; }
private:
bool _adaptive;
bool _fullscreen;
int _level;
bool _objsAreAnim;
bool _axis;
int _repeatCount;
Scheme _defaultScheme;
// .obj files that we've parsed
std::vector<const char *> _objFiles;
// Remaining args that we have not parsed, in order that they've appeared
std::vector<const char *> _remainingArgs;
};
#endif // COMMON_ARGS_H

View File

@ -0,0 +1,44 @@
//
// Copyright 2019 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef SHAPE_DESC_H
#define SHAPE_DESC_H
#include <string>
struct ShapeDesc
{
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme,
bool iIsLeftHanded = false) :
name(iname), data(idata), scheme(ischeme), isLeftHanded(iIsLeftHanded)
{ }
std::string name;
std::string data;
Scheme scheme;
bool isLeftHanded;
};
#endif // SHAPE_DESC_H

View File

@ -0,0 +1,115 @@
//
// Copyright 2019 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../common/viewerArgsUtils.h"
#include "../common/objAnim.h"
#include "../common/shapeDesc.h"
#include <fstream>
#include <sstream>
namespace ViewerArgsUtils {
const ObjAnim *
PopulateAnimShapes(const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes)
{
if (!defaultShapes)
return NULL;
if (args.GetObjFiles().empty())
return NULL;
const ObjAnim *objAnim = ObjAnim::Create(args.GetObjFiles(), args.GetAxis(),
args.GetDefaultScheme());
if (objAnim) {
defaultShapes->push_back(ShapeDesc(args.GetObjFiles()[0], "",
args.GetDefaultScheme()));
}
return objAnim;
}
void
PopulateShapes(const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes)
{
if (!defaultShapes)
return;
if (args.GetObjFiles().empty())
return;
for (size_t i = 0; i < args.GetObjFiles().size(); ++i) {
std::ifstream ifs(args.GetObjFiles()[i]);
if (ifs) {
std::stringstream ss;
ss << ifs.rdbuf();
ifs.close();
std::string str = ss.str();
defaultShapes->push_back(ShapeDesc(
args.GetObjFiles()[i], str.c_str(),
args.GetDefaultScheme()));
} else {
printf("Warning: cannot open shape file '%s'\n",
args.GetObjFiles()[i]);
}
}
}
void
PopulateShapesOrAnimShapes(
const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes,
const ObjAnim **objAnim)
{
if (!defaultShapes)
return;
if (args.GetObjFiles().empty())
return;
if (args.GetObjsAreAnim()) {
if (!objAnim) {
printf("Warning: animations of objs are unsupported in this "
"viewer.\n");
return;
}
*objAnim = PopulateAnimShapes(args, defaultShapes);
} else {
PopulateShapes(args, defaultShapes);
}
}
}

View File

@ -0,0 +1,61 @@
//
// Copyright 2019 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef VIEWER_ARGS_UTILS_H
#define VIEWER_ARGS_UTILS_H
#include "../../regression/common/shape_utils.h"
#include "../common/argOptions.h"
#include "../common/shapeDesc.h"
class ObjAnim;
#include <vector>
namespace ViewerArgsUtils {
// From the list of obj files in args, populates the
// defaultShapes vector, treating the objs as an animated series, returning
// an ObjAnim object.
const ObjAnim *PopulateAnimShapes(const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes);
// From the list of obj files in args, populates the
// defaultShapes vector.
void PopulateShapes(const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes);
// From the list of obj files in args, populates the
// defaultShapes vector and the objAnim object if animated objs have
// been specified in args.
void PopulateShapesOrAnimShapes(
const ArgOptions &args,
std::vector<ShapeDesc> *defaultShapes,
const ObjAnim **objAnim);
} // namespace ViewerArgsUtils
#endif // VIEWER_ARGS_UTILS_H

View File

@ -36,11 +36,13 @@ GLFWmonitor* g_primary = 0;
OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
#include "../../regression/common/far_utils.h"
#include "../common/argOptions.h"
#include "../common/stopwatch.h"
#include "../common/simple_math.h"
#include "../common/glControlMeshDisplay.h"
#include "../common/glHud.h"
#include "../common/glShaderCache.h"
#include "../common/viewerArgsUtils.h"
#include <opensubdiv/osd/glslPatchShaderSource.h>
static const char *shaderSource =
@ -76,8 +78,7 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation g_fvarBoundary =
OpenSubdiv::Sdc::Options::FVAR_LINEAR_ALL;
// GUI variables
int g_fullscreen = 0,
g_freeze = 0,
int g_freeze = 0,
g_displayStyle = kWireShaded,
g_adaptive = 1,
g_smoothCornerPatch = 0,
@ -1262,45 +1263,16 @@ parseIntArg(const char* argString, int dfltValue = 0) {
//------------------------------------------------------------------------------
int main(int argc, char ** argv) {
bool fullscreen = false;
Scheme defaultScheme = kCatmark;
std::vector<char const *> objfiles;
ArgOptions args;
args.Parse(argc, argv);
args.PrintUnrecognizedArgsWarnings();
for (int i = 1; i < argc; ++i) {
if (strstr(argv[i], ".obj")) {
objfiles.push_back(argv[i]);
} else if (!strcmp(argv[i], "-a")) {
g_adaptive = true;
} else if (!strcmp(argv[i], "-u")) {
g_adaptive = false;
} else if (!strcmp(argv[i], "-l")) {
if (++i < argc) g_level = parseIntArg(argv[i], g_level);
} else if (!strcmp(argv[i], "-c")) {
if (++i < argc) g_repeatCount = parseIntArg(argv[i], g_repeatCount);
} else if (!strcmp(argv[i], "-f")) {
fullscreen = true;
} else if (!strcmp(argv[i], "-bilinear")) {
defaultScheme = kBilinear;
} else if (!strcmp(argv[i], "-catmark")) {
defaultScheme = kCatmark;
} else if (!strcmp(argv[i], "-loop")) {
defaultScheme = kLoop;
} else {
printf("Warning: unrecognized argument '%s' ignored\n", argv[i]);
}
}
for (int i = 0; i < (int)objfiles.size(); ++i) {
std::ifstream ifs(objfiles[i]);
if (ifs) {
std::stringstream ss;
ss << ifs.rdbuf();
ifs.close();
std::string str = ss.str();
g_defaultShapes.push_back(ShapeDesc(objfiles[i], str.c_str(), defaultScheme));
} else {
printf("Warning: cannot open shape file '%s'\n", objfiles[i]);
}
}
g_adaptive = args.GetAdaptive();
g_level = args.GetLevel();
g_repeatCount = args.GetRepeatCount();
ViewerArgsUtils::PopulateShapes(args, &g_defaultShapes);
initShapes();
@ -1316,7 +1288,7 @@ int main(int argc, char ** argv) {
GLUtils::SetMinimumGLVersion();
if (fullscreen) {
if (args.GetFullScreen()) {
g_primary = glfwGetPrimaryMonitor();
// apparently glfwGetPrimaryMonitor fails under linux : if no primary,
@ -1337,7 +1309,7 @@ int main(int argc, char ** argv) {
}
if (! (g_window=glfwCreateWindow(g_width, g_height, windowTitle,
fullscreen && g_primary ? g_primary : NULL, NULL))) {
args.GetFullScreen() && g_primary ? g_primary : NULL, NULL))) {
std::cerr << "Failed to create OpenGL context.\n";
glfwTerminate();
return 1;

View File

@ -24,16 +24,7 @@
#include "../../regression/common/shape_utils.h"
#include "../../regression/shapes/all.h"
struct ShapeDesc {
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme) :
name(iname), data(idata), scheme(ischeme) { }
std::string name,
data;
Scheme scheme;
};
#include "../common/shapeDesc.h"
static std::vector<ShapeDesc> g_defaultShapes;

View File

@ -74,6 +74,7 @@ OpenSubdiv::Osd::GLLegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL;
bool g_legacyGregoryEnabled = false;
#include "../../regression/common/far_utils.h"
#include "../common/argOptions.h"
#include "../common/glHud.h"
#include "../common/glUtils.h"
#include "../common/glControlMeshDisplay.h"
@ -81,6 +82,7 @@ bool g_legacyGregoryEnabled = false;
#include "../common/objAnim.h"
#include "../common/simple_math.h"
#include "../common/stopwatch.h"
#include "../common/viewerArgsUtils.h"
#include <opensubdiv/osd/glslPatchShaderSource.h>
@ -172,15 +174,12 @@ int g_currentShape = 0;
ObjAnim const * g_objAnim = 0;
bool g_axis=true;
int g_frame = 0,
g_repeatCount = 0;
float g_animTime = 0;
// GUI variables
int g_fullscreen = 0,
g_freeze = 0,
int g_freeze = 0,
g_shadingMode = kShadingPatchType,
g_displayStyle = kDisplayStyleWireOnShaded,
g_adaptive = 1,
@ -1651,62 +1650,27 @@ callbackErrorGLFW(int error, const char* description) {
int main(int argc, char ** argv) {
bool fullscreen = false;
Scheme defaultScheme = kCatmark;
std::vector<char const *> objfiles;
bool objAnimFlag = false;
ArgOptions args;
args.Parse(argc, argv);
for (int i = 1; i < argc; ++i) {
if (strstr(argv[i], ".obj")) {
objfiles.push_back(argv[i]);
} else if (!strcmp(argv[i], "-a")) {
g_adaptive = true;
} else if (!strcmp(argv[i], "-u")) {
g_adaptive = false;
} else if (!strcmp(argv[i], "-l")) {
if (++i < argc) g_level = atoi(argv[i]);
} else if (!strcmp(argv[i], "-axis")) {
g_axis = false;
} else if (!strcmp(argv[i], "-c")) {
if (++i < argc) g_repeatCount = atoi(argv[i]);
} else if (!strcmp(argv[i], "-f")) {
fullscreen = true;
} else if (!strcmp(argv[i], "-anim")) {
objAnimFlag = true;
} else if (!strcmp(argv[i], "-bilinear")) {
defaultScheme = kBilinear;
} else if (!strcmp(argv[i], "-catmark")) {
defaultScheme = kCatmark;
} else if (!strcmp(argv[i], "-loop")) {
defaultScheme = kLoop;
} else if (!strcmp(argv[i], "-lg")) {
g_adaptive = args.GetAdaptive();
g_level = args.GetLevel();
g_repeatCount = args.GetRepeatCount();
// Parse remaining args
const std::vector<const char *> &rargs = args.GetRemainingArgs();
for (size_t i = 0; i < rargs.size(); ++i) {
if (!strcmp(rargs[i], "-lg")) {
g_legacyGregoryEnabled = true;
} else {
printf("Warning: unrecognized argument '%s' ignored\n", argv[i]);
args.PrintUnrecognizedArgWarning(rargs[i]);
}
}
if (! objfiles.empty()) {
if (objAnimFlag) {
g_objAnim = ObjAnim::Create(objfiles, g_axis, defaultScheme);
if (g_objAnim) {
g_defaultShapes.push_back(ShapeDesc(objfiles[0], "", defaultScheme));
}
} else {
for (int i = 0; i < (int)objfiles.size(); ++i) {
std::ifstream ifs(objfiles[i]);
if (ifs) {
std::stringstream ss;
ss << ifs.rdbuf();
ifs.close();
std::string str = ss.str();
g_defaultShapes.push_back(ShapeDesc(objfiles[i], str.c_str(), defaultScheme));
} else {
printf("Warning: cannot open shape file '%s'\n", objfiles[i]);
}
}
}
}
ViewerArgsUtils::PopulateShapesOrAnimShapes(
args, &g_defaultShapes, &g_objAnim);
initShapes();
@ -1724,7 +1688,7 @@ int main(int argc, char ** argv) {
GLUtils::SetMinimumGLVersion(argc, argv);
if (fullscreen) {
if (args.GetFullScreen()) {
g_primary = glfwGetPrimaryMonitor();
@ -1746,7 +1710,7 @@ int main(int argc, char ** argv) {
}
g_window = glfwCreateWindow(g_width, g_height, windowTitle,
fullscreen && g_primary ? g_primary : NULL, NULL);
args.GetFullScreen() && g_primary ? g_primary : NULL, NULL);
if (! g_window) {
std::cerr << "Failed to create OpenGL context.\n";

View File

@ -25,17 +25,7 @@
#include "../../regression/common/shape_utils.h"
#include "../../regression/shapes/all.h"
struct ShapeDesc {
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme,
bool iIsLeftHanded = false) :
name(iname), data(idata), scheme(ischeme), isLeftHanded(iIsLeftHanded) { }
std::string name;
std::string data;
Scheme scheme;
bool isLeftHanded;
};
#include "../common/shapeDesc.h"
static std::vector<ShapeDesc> g_defaultShapes;