Compare commits
22 Commits
warn
...
f37fed32f3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f37fed32f3 | ||
|
|
85d92bb5cb | ||
|
|
40d00fd935 | ||
|
|
7712f1bebd | ||
|
|
e96e994355 | ||
|
|
8f16866c37 | ||
|
|
5e668b398a | ||
|
|
df3bb6f8e8 | ||
|
|
546aa09d8d | ||
|
|
aa90b5466f | ||
|
|
b404f3af67 | ||
|
|
a957ebe002 | ||
|
|
d793bfb405 | ||
|
|
0ab0146296 | ||
|
|
20d122f305 | ||
|
|
850d0ffdfa | ||
|
|
80058fdcb0 | ||
|
|
1a7aea4ac1 | ||
|
|
178ef391c7 | ||
|
|
59b4d7ccef | ||
|
|
6f990e2b6c | ||
|
|
7fb5056a53 |
@@ -46,15 +46,13 @@ set(TINYOBJLOADER_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
set(TINYOBJLOADER_RUNTIME_DIR ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
option(TINYOBJLOADER_BUILD_TEST_LOADER "Build Example Loader Application" OFF)
|
||||
option(TINYOBJLOADER_COMPILATION_SHARED "Build as shared library" OFF)
|
||||
|
||||
if(TINYOBJLOADER_COMPILATION_SHARED)
|
||||
add_library(${LIBRARY_NAME} SHARED ${tinyobjloader-Source})
|
||||
add_library(${LIBRARY_NAME} ${tinyobjloader-Source})
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES
|
||||
SOVERSION ${TINYOBJLOADER_SOVERSION}
|
||||
)
|
||||
else()
|
||||
add_library(${LIBRARY_NAME} STATIC ${tinyobjloader-Source})
|
||||
endif()
|
||||
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${TINYOBJLOADER_VERSION})
|
||||
@@ -120,6 +118,8 @@ install(TARGETS
|
||||
)
|
||||
install(EXPORT
|
||||
${PROJECT_NAME}-targets
|
||||
NAMESPACE
|
||||
tinyobjloader::
|
||||
DESTINATION
|
||||
${TINYOBJLOADER_CMAKE_DIR}
|
||||
)
|
||||
|
||||
@@ -205,8 +205,9 @@ tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
std::string warn;
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, inputfile.c_str());
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, inputfile.c_str());
|
||||
|
||||
if (!err.empty()) { // `err` may contain warning message.
|
||||
std::cerr << err << std::endl;
|
||||
|
||||
@@ -605,19 +605,9 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
|
||||
}
|
||||
|
||||
assemble :
|
||||
|
||||
{
|
||||
// = pow(5.0, exponent);
|
||||
double a = 1.0;
|
||||
for (int i = 0; i < exponent; i++) {
|
||||
a = a * 5.0;
|
||||
}
|
||||
*result =
|
||||
//(sign == '+' ? 1 : -1) * ldexp(mantissa * pow(5.0, exponent), exponent);
|
||||
(sign == '+' ? 1 : -1) * (mantissa * a) *
|
||||
static_cast<double>(1ULL << exponent); // 5.0^exponent * 2^exponent
|
||||
}
|
||||
|
||||
*result = (sign == '+' ? 1 : -1) *
|
||||
(exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent)
|
||||
: mantissa);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
@@ -1424,8 +1414,9 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
}
|
||||
|
||||
if (command.type == COMMAND_MTLLIB) {
|
||||
// Save the indices of the `mtllib` command in `commands` to easily find it later
|
||||
mtllib_t_index = t;
|
||||
mtllib_i_index = commands->size();
|
||||
mtllib_i_index = commands[t].size();
|
||||
}
|
||||
|
||||
commands[t].emplace_back(std::move(command));
|
||||
|
||||
148
python/main.cpp
148
python/main.cpp
@@ -18,11 +18,9 @@ typedef std::vector<int> vecti;
|
||||
PyObject* pyTupleFromfloat3(float array[3]) {
|
||||
int i;
|
||||
PyObject* tuple = PyTuple_New(3);
|
||||
|
||||
for (i = 0; i <= 2; i++) {
|
||||
PyTuple_SetItem(tuple, i, PyFloat_FromDouble(array[i]));
|
||||
}
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
||||
@@ -30,32 +28,27 @@ extern "C" {
|
||||
|
||||
static PyObject* pyLoadObj(PyObject* self, PyObject* args) {
|
||||
PyObject *rtndict, *pyshapes, *pymaterials, *pymaterial_indices, *attribobj, *current, *meshobj;
|
||||
|
||||
char const* current_name;
|
||||
char const* filename;
|
||||
vectd vect;
|
||||
std::vector<tinyobj::index_t> indices;
|
||||
std::vector<unsigned char> face_verts;
|
||||
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &filename)) return NULL;
|
||||
|
||||
std::string err;
|
||||
tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename);
|
||||
|
||||
std::string err, warn;
|
||||
tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename);
|
||||
pyshapes = PyDict_New();
|
||||
pymaterials = PyDict_New();
|
||||
pymaterial_indices = PyList_New(0);
|
||||
rtndict = PyDict_New();
|
||||
|
||||
attribobj = PyDict_New();
|
||||
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
current = PyList_New(0);
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
current_name = "vertices";
|
||||
@@ -72,124 +65,137 @@ static PyObject* pyLoadObj(PyObject* self, PyObject* args) {
|
||||
}
|
||||
|
||||
for (vectd::iterator it = vect.begin(); it != vect.end(); it++) {
|
||||
PyList_Insert(current, it - vect.begin(), PyFloat_FromDouble(*it));
|
||||
PyObject* value = PyFloat_FromDouble(*it);
|
||||
PyList_Insert(current, it - vect.begin(), value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(attribobj, current_name, current);
|
||||
Py_DECREF(current);
|
||||
}
|
||||
|
||||
for (std::vector<tinyobj::shape_t>::iterator shape = shapes.begin();
|
||||
shape != shapes.end(); shape++) {
|
||||
for (std::vector<tinyobj::shape_t>::iterator shape = shapes.begin(); shape != shapes.end(); shape++) {
|
||||
meshobj = PyDict_New();
|
||||
tinyobj::mesh_t cm = (*shape).mesh;
|
||||
|
||||
{
|
||||
current = PyList_New(0);
|
||||
|
||||
for (size_t i = 0; i < cm.indices.size(); i++) {
|
||||
// Flatten index array: v_idx, vn_idx, vt_idx, v_idx, vn_idx, vt_idx,
|
||||
// ...
|
||||
PyList_Insert(current, 3 * i + 0,
|
||||
PyLong_FromLong(cm.indices[i].vertex_index));
|
||||
PyList_Insert(current, 3 * i + 1,
|
||||
PyLong_FromLong(cm.indices[i].normal_index));
|
||||
PyList_Insert(current, 3 * i + 2,
|
||||
PyLong_FromLong(cm.indices[i].texcoord_index));
|
||||
PyObject* value = PyLong_FromLong(cm.indices[i].vertex_index);
|
||||
PyList_Insert(current, 3 * i + 0, value);
|
||||
Py_DECREF(value);
|
||||
value = PyLong_FromLong(cm.indices[i].normal_index);
|
||||
PyList_Insert(current, 3 * i + 1, value);
|
||||
Py_DECREF(value);
|
||||
value = PyLong_FromLong(cm.indices[i].texcoord_index);
|
||||
PyList_Insert(current, 3 * i + 2, value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(meshobj, "indices", current);
|
||||
Py_DECREF(current);
|
||||
}
|
||||
|
||||
{
|
||||
current = PyList_New(0);
|
||||
|
||||
for (size_t i = 0; i < cm.num_face_vertices.size(); i++) {
|
||||
// Widen data type to long.
|
||||
PyList_Insert(current, i, PyLong_FromLong(cm.num_face_vertices[i]));
|
||||
PyObject* value = PyLong_FromLong(cm.num_face_vertices[i]);
|
||||
PyList_Insert(current, i, value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(meshobj, "num_face_vertices", current);
|
||||
Py_DECREF(current);
|
||||
}
|
||||
|
||||
{
|
||||
current = PyList_New(0);
|
||||
|
||||
for (size_t i = 0; i < cm.material_ids.size(); i++) {
|
||||
PyList_Insert(current, i, PyLong_FromLong(cm.material_ids[i]));
|
||||
PyObject* value = PyLong_FromLong(cm.material_ids[i]);
|
||||
PyList_Insert(current, i, value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(meshobj, "material_ids", current);
|
||||
Py_DECREF(current);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(pyshapes, (*shape).name.c_str(), meshobj);
|
||||
Py_DECREF(meshobj);
|
||||
}
|
||||
|
||||
for (std::vector<tinyobj::material_t>::iterator mat = materials.begin();
|
||||
mat != materials.end(); mat++) {
|
||||
for (std::vector<tinyobj::material_t>::iterator mat = materials.begin(); mat != materials.end(); mat++) {
|
||||
PyObject* matobj = PyDict_New();
|
||||
PyObject* unknown_parameter = PyDict_New();
|
||||
|
||||
for (std::map<std::string, std::string>::iterator p =
|
||||
mat->unknown_parameter.begin();
|
||||
p != mat->unknown_parameter.end(); ++p) {
|
||||
PyDict_SetItemString(unknown_parameter, p->first.c_str(),
|
||||
PyUnicode_FromString(p->second.c_str()));
|
||||
for (std::map<std::string, std::string>::iterator p = mat->unknown_parameter.begin(); p != mat->unknown_parameter.end(); ++p) {
|
||||
PyObject* value = PyUnicode_FromString(p->second.c_str());
|
||||
PyDict_SetItemString(unknown_parameter, p->first.c_str(), value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(matobj, "shininess",
|
||||
PyFloat_FromDouble(mat->shininess));
|
||||
PyDict_SetItemString(matobj, "ior", PyFloat_FromDouble(mat->ior));
|
||||
PyDict_SetItemString(matobj, "dissolve",
|
||||
PyFloat_FromDouble(mat->dissolve));
|
||||
PyDict_SetItemString(matobj, "illum", PyLong_FromLong(mat->illum));
|
||||
PyDict_SetItemString(matobj, "ambient_texname",
|
||||
PyUnicode_FromString(mat->ambient_texname.c_str()));
|
||||
PyDict_SetItemString(matobj, "diffuse_texname",
|
||||
PyUnicode_FromString(mat->diffuse_texname.c_str()));
|
||||
PyDict_SetItemString(matobj, "specular_texname",
|
||||
PyUnicode_FromString(mat->specular_texname.c_str()));
|
||||
PyDict_SetItemString(
|
||||
matobj, "specular_highlight_texname",
|
||||
PyUnicode_FromString(mat->specular_highlight_texname.c_str()));
|
||||
PyDict_SetItemString(matobj, "bump_texname",
|
||||
PyUnicode_FromString(mat->bump_texname.c_str()));
|
||||
PyDict_SetItemString(
|
||||
matobj, "displacement_texname",
|
||||
PyUnicode_FromString(mat->displacement_texname.c_str()));
|
||||
PyDict_SetItemString(matobj, "alpha_texname",
|
||||
PyUnicode_FromString(mat->alpha_texname.c_str()));
|
||||
PyObject* value = PyFloat_FromDouble(mat->shininess);
|
||||
PyDict_SetItemString(matobj, "shininess", value);
|
||||
Py_DECREF(value);
|
||||
value = PyFloat_FromDouble(mat->ior);
|
||||
PyDict_SetItemString(matobj, "ior", value);
|
||||
Py_DECREF(value);
|
||||
value = PyFloat_FromDouble(mat->dissolve);
|
||||
PyDict_SetItemString(matobj, "dissolve", value);
|
||||
Py_DECREF(value);
|
||||
value = PyLong_FromLong(mat->illum);
|
||||
PyDict_SetItemString(matobj, "illum", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->ambient_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "ambient_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->diffuse_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "diffuse_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->specular_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "specular_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->specular_highlight_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "specular_highlight_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->bump_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "bump_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->displacement_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "displacement_texname", value);
|
||||
Py_DECREF(value);
|
||||
value = PyUnicode_FromString(mat->alpha_texname.c_str());
|
||||
PyDict_SetItemString(matobj, "alpha_texname", value);
|
||||
Py_DECREF(value);
|
||||
PyDict_SetItemString(matobj, "ambient", pyTupleFromfloat3(mat->ambient));
|
||||
PyDict_SetItemString(matobj, "diffuse", pyTupleFromfloat3(mat->diffuse));
|
||||
PyDict_SetItemString(matobj, "specular",
|
||||
pyTupleFromfloat3(mat->specular));
|
||||
PyDict_SetItemString(matobj, "transmittance",
|
||||
pyTupleFromfloat3(mat->transmittance));
|
||||
PyDict_SetItemString(matobj, "emission",
|
||||
pyTupleFromfloat3(mat->emission));
|
||||
PyDict_SetItemString(matobj, "specular", pyTupleFromfloat3(mat->specular));
|
||||
PyDict_SetItemString(matobj, "transmittance", pyTupleFromfloat3(mat->transmittance));
|
||||
PyDict_SetItemString(matobj, "emission", pyTupleFromfloat3(mat->emission));
|
||||
PyDict_SetItemString(matobj, "unknown_parameter", unknown_parameter);
|
||||
|
||||
Py_DECREF(unknown_parameter);
|
||||
PyDict_SetItemString(pymaterials, mat->name.c_str(), matobj);
|
||||
PyList_Append(pymaterial_indices, PyUnicode_FromString(mat->name.c_str()));
|
||||
Py_DECREF(matobj);
|
||||
value = PyUnicode_FromString(mat->name.c_str());
|
||||
PyList_Append(pymaterial_indices, value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(rtndict, "shapes", pyshapes);
|
||||
Py_DECREF(pyshapes);
|
||||
PyDict_SetItemString(rtndict, "materials", pymaterials);
|
||||
Py_DECREF(pymaterials);
|
||||
PyDict_SetItemString(rtndict, "material_indices", pymaterial_indices);
|
||||
Py_DECREF(pymaterial_indices);
|
||||
PyDict_SetItemString(rtndict, "attribs", attribobj);
|
||||
|
||||
Py_DECREF(attribobj);
|
||||
return rtndict;
|
||||
}
|
||||
|
||||
static PyMethodDef mMethods[] = {
|
||||
|
||||
{"LoadObj", pyLoadObj, METH_VARARGS}, {NULL, NULL, 0, NULL}
|
||||
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
||||
static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT, "tinyobjloader",
|
||||
NULL, -1, mMethods};
|
||||
static struct PyModuleDef moduledef = {PyModuleDef_HEAD_INIT, "tinyobjloader", NULL, -1, mMethods};
|
||||
|
||||
PyMODINIT_FUNC PyInit_tinyobjloader(void) {
|
||||
return PyModule_Create(&moduledef);
|
||||
|
||||
@@ -986,6 +986,49 @@ TEST_CASE("multiple-group-names", "[group]") {
|
||||
// single white space.
|
||||
}
|
||||
|
||||
TEST_CASE("initialize_all_texopts", "[ensure unparsed texopts are initialized to defaults]") {
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
std::string warn;
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/cornell_box.obj", gMtlBasePath, false);
|
||||
|
||||
REQUIRE(0 < materials.size());
|
||||
|
||||
#define REQUIRE_DEFAULT_TEXOPT(texopt) \
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_NONE == texopt.type); \
|
||||
REQUIRE(0.0 == texopt.brightness); \
|
||||
REQUIRE(1.0 == texopt.contrast); \
|
||||
REQUIRE(false == texopt.clamp); \
|
||||
REQUIRE(true == texopt.blendu); \
|
||||
REQUIRE(true == texopt.blendv); \
|
||||
REQUIRE(1.0 == texopt.bump_multiplier); \
|
||||
for (int j = 0; j < 3; j++) { \
|
||||
REQUIRE(0.0 == texopt.origin_offset[j]); \
|
||||
REQUIRE(1.0 == texopt.scale[j]); \
|
||||
REQUIRE(0.0 == texopt.turbulence[j]); \
|
||||
}
|
||||
for (size_t i = 0; i < materials.size(); i++) {
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].ambient_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].diffuse_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].specular_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].specular_highlight_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].bump_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].displacement_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].alpha_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].reflection_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].roughness_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].metallic_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].sheen_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].emissive_texopt);
|
||||
REQUIRE_DEFAULT_TEXOPT(materials[i].normal_texopt);
|
||||
}
|
||||
#undef REQUIRE_DEFAULT_TEXOPT
|
||||
}
|
||||
|
||||
TEST_CASE("colorspace", "[Issue184]") {
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
|
||||
@@ -23,6 +23,8 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// version 1.4.0 : Modifed ParseTextureNameAndOption API
|
||||
// version 1.3.1 : Make ParseTextureNameAndOption API public
|
||||
// version 1.3.0 : Separate warning and error message(breaking API of LoadObj)
|
||||
// version 1.2.3 : Added color space extension('-colorspace') to tex opts.
|
||||
// version 1.2.2 : Parse multiple group names.
|
||||
@@ -157,8 +159,8 @@ typedef struct {
|
||||
real_t bump_multiplier; // -bm (for bump maps only, default 1.0)
|
||||
|
||||
// extension
|
||||
std::string colorspace; // Explicitly specify color space of stored value.
|
||||
// Usually `sRGB` or `linear` (default empty).
|
||||
std::string colorspace; // Explicitly specify color space of stored texel
|
||||
// value. Usually `sRGB` or `linear` (default empty).
|
||||
} texture_option_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -386,6 +388,16 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
std::vector<material_t> *materials, std::istream *inStream,
|
||||
std::string *warning, std::string *err);
|
||||
|
||||
///
|
||||
/// Parse texture name and texture option for custom texture parameter through
|
||||
/// material::unknown_parameter
|
||||
///
|
||||
/// @param[out] texname Parsed texture name
|
||||
/// @param[out] texopt Parsed texopt
|
||||
/// @param[in] linebuf Input string
|
||||
///
|
||||
bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt,
|
||||
const char *linebuf);
|
||||
} // namespace tinyobj
|
||||
|
||||
#endif // TINY_OBJ_LOADER_H_
|
||||
@@ -423,7 +435,7 @@ struct face_t {
|
||||
int pad_;
|
||||
std::vector<vertex_index_t> vertex_indices; // face vertex indices.
|
||||
|
||||
face_t() : smoothing_group_id(0) {}
|
||||
face_t() : smoothing_group_id(0), pad_(0) {}
|
||||
};
|
||||
|
||||
struct line_t {
|
||||
@@ -891,37 +903,12 @@ static vertex_index_t parseRawTriple(const char **token) {
|
||||
return vi;
|
||||
}
|
||||
|
||||
static bool ParseTextureNameAndOption(std::string *texname,
|
||||
texture_option_t *texopt,
|
||||
const char *linebuf, const bool is_bump) {
|
||||
bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt,
|
||||
const char *linebuf) {
|
||||
// @todo { write more robust lexer and parser. }
|
||||
bool found_texname = false;
|
||||
std::string texture_name;
|
||||
|
||||
// Fill with default value for texopt.
|
||||
if (is_bump) {
|
||||
texopt->imfchan = 'l';
|
||||
} else {
|
||||
texopt->imfchan = 'm';
|
||||
}
|
||||
texopt->bump_multiplier = static_cast<real_t>(1.0);
|
||||
texopt->clamp = false;
|
||||
texopt->blendu = true;
|
||||
texopt->blendv = true;
|
||||
texopt->sharpness = static_cast<real_t>(1.0);
|
||||
texopt->brightness = static_cast<real_t>(0.0);
|
||||
texopt->contrast = static_cast<real_t>(1.0);
|
||||
texopt->origin_offset[0] = static_cast<real_t>(0.0);
|
||||
texopt->origin_offset[1] = static_cast<real_t>(0.0);
|
||||
texopt->origin_offset[2] = static_cast<real_t>(0.0);
|
||||
texopt->scale[0] = static_cast<real_t>(1.0);
|
||||
texopt->scale[1] = static_cast<real_t>(1.0);
|
||||
texopt->scale[2] = static_cast<real_t>(1.0);
|
||||
texopt->turbulence[0] = static_cast<real_t>(0.0);
|
||||
texopt->turbulence[1] = static_cast<real_t>(0.0);
|
||||
texopt->turbulence[2] = static_cast<real_t>(0.0);
|
||||
texopt->type = TEXTURE_TYPE_NONE;
|
||||
|
||||
const char *token = linebuf; // Assume line ends with NULL
|
||||
|
||||
while (!IS_NEW_LINE((*token))) {
|
||||
@@ -998,7 +985,46 @@ static bool ParseTextureNameAndOption(std::string *texname,
|
||||
}
|
||||
}
|
||||
|
||||
static void InitTexOpt(texture_option_t *texopt, const bool is_bump) {
|
||||
if (is_bump) {
|
||||
texopt->imfchan = 'l';
|
||||
} else {
|
||||
texopt->imfchan = 'm';
|
||||
}
|
||||
texopt->bump_multiplier = static_cast<real_t>(1.0);
|
||||
texopt->clamp = false;
|
||||
texopt->blendu = true;
|
||||
texopt->blendv = true;
|
||||
texopt->sharpness = static_cast<real_t>(1.0);
|
||||
texopt->brightness = static_cast<real_t>(0.0);
|
||||
texopt->contrast = static_cast<real_t>(1.0);
|
||||
texopt->origin_offset[0] = static_cast<real_t>(0.0);
|
||||
texopt->origin_offset[1] = static_cast<real_t>(0.0);
|
||||
texopt->origin_offset[2] = static_cast<real_t>(0.0);
|
||||
texopt->scale[0] = static_cast<real_t>(1.0);
|
||||
texopt->scale[1] = static_cast<real_t>(1.0);
|
||||
texopt->scale[2] = static_cast<real_t>(1.0);
|
||||
texopt->turbulence[0] = static_cast<real_t>(0.0);
|
||||
texopt->turbulence[1] = static_cast<real_t>(0.0);
|
||||
texopt->turbulence[2] = static_cast<real_t>(0.0);
|
||||
texopt->type = TEXTURE_TYPE_NONE;
|
||||
}
|
||||
|
||||
static void InitMaterial(material_t *material) {
|
||||
InitTexOpt(&material->ambient_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->diffuse_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->specular_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->specular_highlight_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->bump_texopt, /* is_bump */ true);
|
||||
InitTexOpt(&material->displacement_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->alpha_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->reflection_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->roughness_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->metallic_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->sheen_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->emissive_texopt, /* is_bump */ false);
|
||||
InitTexOpt(&material->normal_texopt,
|
||||
/* is_bump */ false); // @fixme { is_bump will be true? }
|
||||
material->name = "";
|
||||
material->ambient_texname = "";
|
||||
material->diffuse_texname = "";
|
||||
@@ -1145,20 +1171,34 @@ static bool exportGroupsToShape(shape_t *shape,
|
||||
area += (v0x * v1y - v0y * v1x) * static_cast<real_t>(0.5);
|
||||
}
|
||||
|
||||
int maxRounds = 10; // arbitrary max loop count to protect against
|
||||
// unexpected errors
|
||||
|
||||
face_t remainingFace = face; // copy
|
||||
size_t guess_vert = 0;
|
||||
vertex_index_t ind[3];
|
||||
real_t vx[3];
|
||||
real_t vy[3];
|
||||
while (remainingFace.vertex_indices.size() > 3 && maxRounds > 0) {
|
||||
|
||||
// How many iterations can we do without decreasing the remaining
|
||||
// vertices.
|
||||
size_t remainingIterations = face.vertex_indices.size();
|
||||
size_t previousRemainingVertices = remainingFace.vertex_indices.size();
|
||||
|
||||
while (remainingFace.vertex_indices.size() > 3 && remainingIterations > 0){
|
||||
npolys = remainingFace.vertex_indices.size();
|
||||
if (guess_vert >= npolys) {
|
||||
maxRounds -= 1;
|
||||
guess_vert -= npolys;
|
||||
}
|
||||
|
||||
if (previousRemainingVertices != npolys) {
|
||||
// The number of remaining vertices decreased. Reset counters.
|
||||
previousRemainingVertices = npolys;
|
||||
remainingIterations = npolys;
|
||||
} else {
|
||||
// We didn't consume a vertex on previous iteration, reduce the
|
||||
// available iterations.
|
||||
remainingIterations--;
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < 3; k++) {
|
||||
ind[k] = remainingFace.vertex_indices[(guess_vert + k) % npolys];
|
||||
size_t vi = size_t(ind[k].v_idx);
|
||||
@@ -1469,9 +1509,9 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
|
||||
if (has_tr) {
|
||||
warn_ss << "Both `d` and `Tr` parameters defined for \""
|
||||
<< material.name << "\". Use the value of `d` for dissolve (line "
|
||||
<< line_no << " in .mtl.)"
|
||||
<< std::endl;
|
||||
<< material.name
|
||||
<< "\". Use the value of `d` for dissolve (line " << line_no
|
||||
<< " in .mtl.)" << std::endl;
|
||||
}
|
||||
has_d = true;
|
||||
continue;
|
||||
@@ -1481,9 +1521,9 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if (has_d) {
|
||||
// `d` wins. Ignore `Tr` value.
|
||||
warn_ss << "Both `d` and `Tr` parameters defined for \""
|
||||
<< material.name << "\". Use the value of `d` for dissolve (line "
|
||||
<< line_no << " in .mtl.)"
|
||||
<< std::endl;
|
||||
<< material.name
|
||||
<< "\". Use the value of `d` for dissolve (line " << line_no
|
||||
<< " in .mtl.)" << std::endl;
|
||||
} else {
|
||||
// We invert value of Tr(assume Tr is in range [0, 1])
|
||||
// NOTE: Interpretation of Tr is application(exporter) dependent. For
|
||||
@@ -1547,8 +1587,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.ambient_texname),
|
||||
&(material.ambient_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.ambient_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1556,8 +1595,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.diffuse_texname),
|
||||
&(material.diffuse_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.diffuse_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1565,8 +1603,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.specular_texname),
|
||||
&(material.specular_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.specular_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1574,8 +1611,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.specular_highlight_texname),
|
||||
&(material.specular_highlight_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.specular_highlight_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1583,8 +1619,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_bump", 8)) && IS_SPACE(token[8])) {
|
||||
token += 9;
|
||||
ParseTextureNameAndOption(&(material.bump_texname),
|
||||
&(material.bump_texopt), token,
|
||||
/* is_bump */ true);
|
||||
&(material.bump_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1592,8 +1627,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Bump", 8)) && IS_SPACE(token[8])) {
|
||||
token += 9;
|
||||
ParseTextureNameAndOption(&(material.bump_texname),
|
||||
&(material.bump_texopt), token,
|
||||
/* is_bump */ true);
|
||||
&(material.bump_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1601,8 +1635,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) {
|
||||
token += 5;
|
||||
ParseTextureNameAndOption(&(material.bump_texname),
|
||||
&(material.bump_texopt), token,
|
||||
/* is_bump */ true);
|
||||
&(material.bump_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1611,8 +1644,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
token += 6;
|
||||
material.alpha_texname = token;
|
||||
ParseTextureNameAndOption(&(material.alpha_texname),
|
||||
&(material.alpha_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.alpha_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1620,8 +1652,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) {
|
||||
token += 5;
|
||||
ParseTextureNameAndOption(&(material.displacement_texname),
|
||||
&(material.displacement_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.displacement_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1629,8 +1660,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "refl", 4)) && IS_SPACE(token[4])) {
|
||||
token += 5;
|
||||
ParseTextureNameAndOption(&(material.reflection_texname),
|
||||
&(material.reflection_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.reflection_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1638,8 +1668,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.roughness_texname),
|
||||
&(material.roughness_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.roughness_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1647,8 +1676,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.metallic_texname),
|
||||
&(material.metallic_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.metallic_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1656,8 +1684,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.sheen_texname),
|
||||
&(material.sheen_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.sheen_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1665,17 +1692,15 @@ void LoadMtl(std::map<std::string, int> *material_map,
|
||||
if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) {
|
||||
token += 7;
|
||||
ParseTextureNameAndOption(&(material.emissive_texname),
|
||||
&(material.emissive_texopt), token,
|
||||
/* is_bump */ false);
|
||||
&(material.emissive_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
// PBR: normal map texture
|
||||
if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) {
|
||||
token += 5;
|
||||
ParseTextureNameAndOption(
|
||||
&(material.normal_texname), &(material.normal_texopt), token,
|
||||
/* is_bump */ false); // @fixme { is_bump will be true? }
|
||||
ParseTextureNameAndOption(&(material.normal_texname),
|
||||
&(material.normal_texopt), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1934,7 +1959,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
static_cast<int>(vt.size() / 2), &vi)) {
|
||||
if (err) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed parse `f' line(e.g. zero value for face index. line " << line_num << ".)\n";
|
||||
ss << "Failed parse `f' line(e.g. zero value for face index. line "
|
||||
<< line_num << ".)\n";
|
||||
(*err) += ss.str();
|
||||
}
|
||||
return false;
|
||||
@@ -1996,7 +2022,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
if (warn) {
|
||||
std::stringstream ss;
|
||||
ss << "Looks like empty filename for mtllib. Use default "
|
||||
"material (line " << line_num << ".)\n";
|
||||
"material (line "
|
||||
<< line_num << ".)\n";
|
||||
|
||||
(*warn) += ss.str();
|
||||
}
|
||||
@@ -2205,21 +2232,24 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
if (greatest_v_idx >= static_cast<int>(v.size() / 3)) {
|
||||
if (warn) {
|
||||
std::stringstream ss;
|
||||
ss << "Vertex indices out of bounds (line " << line_num << ".)\n" << std::endl;
|
||||
ss << "Vertex indices out of bounds (line " << line_num << ".)\n"
|
||||
<< std::endl;
|
||||
(*warn) += ss.str();
|
||||
}
|
||||
}
|
||||
if (greatest_vn_idx >= static_cast<int>(vn.size() / 3)) {
|
||||
if (warn) {
|
||||
std::stringstream ss;
|
||||
ss << "Vertex normal indices out of bounds (line " << line_num << ".)\n" << std::endl;
|
||||
ss << "Vertex normal indices out of bounds (line " << line_num << ".)\n"
|
||||
<< std::endl;
|
||||
(*warn) += ss.str();
|
||||
}
|
||||
}
|
||||
if (greatest_vt_idx >= static_cast<int>(vt.size() / 2)) {
|
||||
if (warn) {
|
||||
std::stringstream ss;
|
||||
ss << "Vertex texcoord indices out of bounds (line " << line_num << ".)\n" << std::endl;
|
||||
ss << "Vertex texcoord indices out of bounds (line " << line_num << ".)\n"
|
||||
<< std::endl;
|
||||
(*warn) += ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user