mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Add some code for USDA parser.
This commit is contained in:
67
models/hair.usda
Normal file
67
models/hair.usda
Normal 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
28
sandbox/usda/Makefile
Normal 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
273
sandbox/usda/usda-parser.cc
Normal 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;
|
||||
}
|
||||
@@ -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_; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user