Add some code for USDA parser.

This commit is contained in:
Syoyo Fujita
2020-10-19 20:18:31 +09:00
parent cae6595a1f
commit 2b56864ed0
4 changed files with 370 additions and 1 deletions

67
models/hair.usda Normal file
View File

@@ -0,0 +1,67 @@
#usda 1.0
(
doc = "Blender v2.83.7"
metersPerUnit = 1
upAxis = "Z"
)
def Xform "Light"
{
matrix4d xformOp:transform = ( (-0.29086464643478394, 0.9551711678504944, -0.05518905818462372, 0), (-0.7711008191108704, -0.1998833566904068, 0.6045247316360474, 0), (0.5663931965827942, 0.21839119493961334, 0.7946722507476807, 0), (4.076245307922363, 1.0054539442062378, 5.903861999511719, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def SphereLight "Light"
{
color3f color = (1, 1, 1)
float intensity = 10
float radius = 0.1
float specular = 1
}
}
def Xform "Camera"
{
matrix4d xformOp:transform = ( (0.6859206557273865, 0.7276763319969177, 0, 0), (-0.32401347160339355, 0.305420845746994, 0.8953956365585327, 0), (0.6515582203865051, -0.6141703724861145, 0.44527140259742737, 0), (7.358891487121582, -6.925790786743164, 4.958309173583984, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def Camera "Camera"
{
float2 clippingRange = (0.1, 100)
float focalLength = 50
float horizontalAperture = 36
float horizontalApertureOffset = 0
token projection = "perspective"
float verticalAperture = 20.25
float verticalApertureOffset = 0
}
}
def Xform "Plane"
{
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def BasisCurves "ParticleSettings"
{
uniform token basis = "bspline"
int[] curveVertexCounts = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
point3f[] points = [(0.0825153, -0.7126689, 0), (0.0825153, -0.7126689, 0.41532692), (0.0825153, -0.7126689, 0.99539745), (0.0825153, -0.7126689, 1.4209023), (0.0825153, -0.7126689, 1.9300001), (0.0825153, -0.7126689, 2.439098), (0.0825153, -0.7126689, 2.8646023), (0.0825153, -0.7126689, 3.4446728), (0.0825153, -0.7126689, 3.8599997), (-0.74895674, -0.42046744, 0), (-0.74895674, -0.42046744, 0.41532692), (-0.74895674, -0.42046744, 0.99539745), (-0.74895674, -0.42046744, 1.4209023), (-0.74895674, -0.42046744, 1.9300001), (-0.74895674, -0.42046744, 2.439098), (-0.74895674, -0.42046744, 2.8646023), (-0.74895674, -0.42046744, 3.4446728), (-0.74895674, -0.42046744, 3.8599997), (-0.84020585, -0.8705612, 0), (-0.84020585, -0.8705612, 0.41532692), (-0.84020585, -0.8705612, 0.99539745), (-0.84020585, -0.8705612, 1.4209023), (-0.84020585, -0.8705612, 1.9300001), (-0.84020585, -0.8705612, 2.439098), (-0.84020585, -0.8705612, 2.8646023), (-0.84020585, -0.8705612, 3.4446728), (-0.84020585, -0.8705612, 3.8599997), (0.76589143, -0.48999798, 0), (0.76589143, -0.48999798, 0.41532692), (0.76589143, -0.48999798, 0.99539745), (0.76589143, -0.48999798, 1.4209023), (0.76589143, -0.48999798, 1.9300001), (0.76589143, -0.48999798, 2.439098), (0.76589143, -0.48999798, 2.8646023), (0.76589143, -0.48999798, 3.4446728), (0.76589143, -0.48999798, 3.8599997), (0.6797011, 0.63009846, 0), (0.6797011, 0.63009846, 0.41532692), (0.6797011, 0.63009846, 0.99539745), (0.6797011, 0.63009846, 1.4209023), (0.6797011, 0.63009846, 1.9300001), (0.6797011, 0.63009846, 2.439098), (0.6797011, 0.63009846, 2.8646023), (0.6797011, 0.63009846, 3.4446728), (0.6797011, 0.63009846, 3.8599997), (0.96835244, 0.24794665, 0), (0.96835244, 0.24794665, 0.41532692), (0.96835244, 0.24794665, 0.99539745), (0.96835244, 0.24794665, 1.4209023), (0.96835244, 0.24794665, 1.9300001), (0.96835244, 0.24794665, 2.439098), (0.96835244, 0.24794665, 2.8646023), (0.96835244, 0.24794665, 3.4446728), (0.96835244, 0.24794665, 3.8599997), (0.52848554, -0.86063015, 0), (0.52848554, -0.86063015, 0.41532692), (0.52848554, -0.86063015, 0.99539745), (0.52848554, -0.86063015, 1.4209023), (0.52848554, -0.86063015, 1.9300001), (0.52848554, -0.86063015, 2.439098), (0.52848554, -0.86063015, 2.8646023), (0.52848554, -0.86063015, 3.4446728), (0.52848554, -0.86063015, 3.8599997), (-0.20061585, 0.57317805, 0), (-0.20061585, 0.57317805, 0.41532692), (-0.20061585, 0.57317805, 0.99539745), (-0.20061585, 0.57317805, 1.4209023), (-0.20061585, 0.57317805, 1.9300001), (-0.20061585, 0.57317805, 2.439098), (-0.20061585, 0.57317805, 2.8646023), (-0.20061585, 0.57317805, 3.4446728), (-0.20061585, 0.57317805, 3.8599997), (-0.3693127, -0.7677623, 0), (-0.3693127, -0.7677623, 0.41532692), (-0.3693127, -0.7677623, 0.99539745), (-0.3693127, -0.7677623, 1.4209023), (-0.3693127, -0.7677623, 1.9300001), (-0.3693127, -0.7677623, 2.439098), (-0.3693127, -0.7677623, 2.8646023), (-0.3693127, -0.7677623, 3.4446728), (-0.3693127, -0.7677623, 3.8599997), (0.24664283, 0.7816913, 0), (0.24664283, 0.7816913, 0.41532692), (0.24664283, 0.7816913, 0.99539745), (0.24664283, 0.7816913, 1.4209023), (0.24664283, 0.7816913, 1.9300001), (0.24664283, 0.7816913, 2.439098), (0.24664283, 0.7816913, 2.8646023), (0.24664283, 0.7816913, 3.4446728), (0.24664283, 0.7816913, 3.8599997)]
color3f[] primvars:displayColor = [(0.5, 0.5, 0.5)]
uniform token type = "cubic"
}
def Mesh "Plane"
{
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
normal3f[] normals = [(0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1)] (
interpolation = "faceVarying"
)
point3f[] points = [(-1, -1, 0), (1, -1, 0), (-1, 1, 0), (1, 1, 0)]
texCoord2f[] primvars:UVMap = [(0, 0), (1, 0), (1, 1), (0, 1)] (
interpolation = "faceVarying"
)
uniform token subdivisionScheme = "none"
}
}

28
sandbox/usda/Makefile Normal file
View File

@@ -0,0 +1,28 @@
CC=clang
CXX=clang++
INCFLAGS=-I../../src/external/ryu -I../../src
# only applied to usda-parser.cc
EXTRA_COMPILER_FLAGS=-Weverything -Werror -Wno-padded -Wno-c++98-compat
CXXFLAGS=-std=c++11 -fsanitize=address
LDFLAGS=-fsanitize=address
.PHONY: clean all
all: usda-parser
usda-parser: usda-parser.o d2s.o f2s.o
$(CXX) $(LDFLAGS) -o $@ $^
usda-parser.o: usda-parser.cc
$(CXX) $(INCFLAGS) $(CXXFLAGS) $(EXTRA_COMPILER_FLAGS) -c -o $@ $<
d2s.o: ../../src/external/ryu/ryu/d2s.c
$(CC) $(INCFLAGS) $(CXXFLAGS) -c -o $@ $<
f2s.o: ../../src/external/ryu/ryu/f2s.c
$(CC) $(INCFLAGS) $(CXXFLAGS) -c -o $@ $<
clean:
@rm -rf usda-parser usda-parser.o d2s.o f2s.o

273
sandbox/usda/usda-parser.cc Normal file
View File

@@ -0,0 +1,273 @@
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <cassert>
#include <stack>
#include <sstream>
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Weverything"
#endif
#include <ryu/ryu.h>
#include <ryu/ryu_parse.h>
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#include <stream-reader.hh>
namespace tinyusdz {
struct ErrorDiagnositc
{
std::string err;
int line_row = -1;
int line_col = -1;
};
class USDAParser
{
public:
struct ParseState {
int64_t loc{-1}; // byte location in StreamReder
};
USDAParser(tinyusdz::StreamReader *sr) : _sr(sr) {
}
bool SkipUntilNewline() {
while (!_sr->eof()) {
char c;
if (!_sr->read1(&c)) {
// this should not happen.
return false;
}
if ((c == '\n') || (c == '\r')) {
// continue
} else {
break;
}
}
_line_row++;
return true;
}
bool SkipWhitespace() {
while (!_sr->eof()) {
char c;
if (!_sr->read1(&c)) {
// this should not happen.
return false;
}
if ((c == ' ') || (c == '\t') || (c == '\f')) {
// continue
} else {
break;
}
}
// unwind 1 char
if (!_sr->seek_from_current(-1)) {
return false;
}
return true;
}
// #usda FLOAT
// `#` style comment
bool ParseHeader() {
SkipWhitespace();
if (_sr->eof()) {
return false;
}
{
char magic[5];
if (!_sr->read(5, 5, reinterpret_cast<uint8_t*>(magic))) {
// eol
return false;
}
if ((magic[0] == '#') && (magic[1] == 'u') &&
(magic[2] == 's') && (magic[3] == 'd') &&
(magic[4] == 'a')) {
// ok
} else {
ErrorDiagnositc diag;
diag.line_row = _line_row;
diag.line_col = _line_col;
diag.err = "Magic header must be `#usda` but got `" + std::string(magic, 5) + "`\n";
err_stack.push(diag);
return false;
}
}
if (!SkipWhitespace()) {
// eof
return false;
}
// current we only accept "1.0"
{
char ver[3];
if (!_sr->read(3, 3, reinterpret_cast<uint8_t*>(ver))) {
return false;
}
if ((ver[0] == '1') && (ver[1] == '.') &&
(ver[2] == '0')) {
// ok
_version = 1.0f;
} else {
ErrorDiagnositc diag;
diag.line_row = _line_row;
diag.line_col = _line_col;
diag.err = "Version must be `1.0` but got `" + std::string(ver, 3) + "`\n";
err_stack.push(diag);
return false;
}
}
SkipUntilNewline();
return true;
}
// `#` style comment
bool ParseSharpComment() {
char c;
if (!_sr->read1(&c)) {
// eol
return false;
}
if (c != '#') {
return false;
}
return true;
}
bool Push() {
// Stack size must be less than the number of input bytes.
assert (parse_stack.size() < _sr->size());
uint64_t loc = _sr->tell();
ParseState state;
state.loc = int64_t(loc);
parse_stack.push(state);
return true;
}
bool Pop(ParseState *state) {
if (parse_stack.empty()) {
return false;
}
(*state) = parse_stack.top();
parse_stack.pop();
return true;
}
bool Parse() {
bool ok{false};
ok = ParseHeader();
return ok;
}
std::string GetError() {
if (err_stack.empty()) {
return std::string();
}
ErrorDiagnositc diag = err_stack.top();
std::stringstream ss;
ss << "line " << diag.line_row << ", col " << diag.line_col << ": ";
ss << diag.err << "\n";
return ss.str();
}
private:
const tinyusdz::StreamReader *_sr = nullptr;
std::stack<ErrorDiagnositc> err_stack;
std::stack<ParseState> parse_stack;
int _line_row{0};
int _line_col{0};
float _version{1.0f};
};
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Need input.usda\n";
exit(-1);
}
std::string filename = argv[1];
std::vector<uint8_t> data;
{
// TODO(syoyo): Support UTF-8 filename
std::ifstream ifs(filename.c_str(), std::ifstream::binary);
if (!ifs) {
std::cerr << "Failed to open file: " << filename << "\n";
return -1;
}
// TODO(syoyo): Use mmap
ifs.seekg(0, ifs.end);
size_t sz = static_cast<size_t>(ifs.tellg());
if (int64_t(sz) < 0) {
// Looks reading directory, not a file.
std::cerr << "Looks like filename is a directory : \"" << filename << "\"\n";
return -1;
}
data.resize(sz);
ifs.seekg(0, ifs.beg);
ifs.read(reinterpret_cast<char *>(&data.at(0)),
static_cast<std::streamsize>(sz));
}
tinyusdz::StreamReader sr(data.data(), data.size(), /* swap endian */false);
tinyusdz::USDAParser parser(&sr);
{
bool ret = parser.Parse();
if (!ret) {
std::cerr << "Failed to parse .usda: \n";
std::cerr << parser.GetError() << "\n";
}
std::cout << "ok\n";
}
return 0;
}

View File

@@ -121,7 +121,7 @@ class StreamReader {
return true;
}
bool seek_from_currect(const int64_t offset) const {
bool seek_from_current(const int64_t offset) const {
if ((int64_t(idx_) + offset) < 0) {
return false;
}
@@ -340,6 +340,7 @@ class StreamReader {
#endif
size_t tell() const { return size_t(idx_); }
bool eof() const { return idx_ >= length_; }
const uint8_t *data() const { return binary_; }