Fix a shape is lost if obj ends with a 'usemtl'. Fixes #104

This commit is contained in:
Syoyo Fujita
2016-10-18 17:33:28 +09:00
parent 3ddad1e377
commit 039d4a6c54
3 changed files with 55 additions and 2 deletions

View File

@@ -0,0 +1,30 @@
# cornell_box.obj and cornell_box.mtl are grabbed from Intel's embree project.
# original cornell box data
# comment
# empty line including some space
mtllib cornell_box.mtl
o floor
v 552.8 0.0 0.0
v 0.0 0.0 0.0
v 0.0 0.0 559.2
v 549.6 0.0 559.2
v 130.0 0.0 65.0
v 82.0 0.0 225.0
v 240.0 0.0 272.0
v 290.0 0.0 114.0
v 423.0 0.0 247.0
v 265.0 0.0 296.0
v 314.0 0.0 456.0
v 472.0 0.0 406.0
f 1 2 3 4
f 8 7 6 5
f 12 11 10 9
usemtl white

View File

@@ -402,6 +402,7 @@ TEST_CASE("transmittance_filter_Tf", "[Issue95-Tf]") {
REQUIRE(0.2 == Approx(materials[0].transmittance[1])); REQUIRE(0.2 == Approx(materials[0].transmittance[1]));
REQUIRE(0.3 == Approx(materials[0].transmittance[2])); REQUIRE(0.3 == Approx(materials[0].transmittance[2]));
} }
TEST_CASE("transmittance_filter_Kt", "[Issue95-Kt]") { TEST_CASE("transmittance_filter_Kt", "[Issue95-Kt]") {
tinyobj::attrib_t attrib; tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::shape_t> shapes;
@@ -420,6 +421,21 @@ TEST_CASE("transmittance_filter_Kt", "[Issue95-Kt]") {
REQUIRE(0.3 == Approx(materials[0].transmittance[2])); REQUIRE(0.3 == Approx(materials[0].transmittance[2]));
} }
TEST_CASE("usemtl_at_last_line", "[Issue104]") {
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, "../models/usemtl-issue-104.obj", gMtlBasePath);
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(1 == shapes.size());
}
#if 0 #if 0
int int
main( main(

View File

@@ -23,6 +23,7 @@ THE SOFTWARE.
*/ */
// //
// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104)
// version 1.0.0 : Change data structure. Change license from BSD to MIT. // version 1.0.0 : Change data structure. Change license from BSD to MIT.
// //
@@ -1161,7 +1162,9 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
} }
if (newMaterialId != material) { if (newMaterialId != material) {
// Create per-face material // Create per-face material. Thus we don't add `shape` to `shapes` at
// this time.
// just clear `faceGroup` after `exportFaceGroupToShape()` call.
exportFaceGroupToShape(&shape, faceGroup, tags, material, name, exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
triangulate); triangulate);
faceGroup.clear(); faceGroup.clear();
@@ -1307,7 +1310,11 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
triangulate); triangulate);
if (ret) { // exportFaceGroupToShape return false when `usemtl` is called in the last
// line.
// we also add `shape` to `shapes` when `shape.mesh` has already some
// faces(indices)
if (ret || shape.mesh.indices.size()) {
shapes->push_back(shape); shapes->push_back(shape);
} }
faceGroup.clear(); // for safety faceGroup.clear(); // for safety