Skip to content

Commit

Permalink
Port over #117
Browse files Browse the repository at this point in the history
  • Loading branch information
lilleyse committed Nov 1, 2018
1 parent 05e9788 commit 96154b5
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Change Log
* Added ability to use the first material in the mtl file when the obj is missing `usemtl`. [#163](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/163)
* Fixed loading faces that contain less than 3 vertices. [#163](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/163)
* Fixed loading mtllib paths that contain spaces. [#163](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/163)
* Attempt to load missing materials and textures from within the same directory as the obj. [#163](https://github.com/AnalyticalGraphicsInc/obj2gltf/pull/163)

### 1.3.4 2018-10-16

Expand Down
76 changes: 52 additions & 24 deletions lib/loadObj.js
Original file line number Diff line number Diff line change
Expand Up @@ -463,13 +463,11 @@ function normalizeMtlPath(mtlPath, objDirectory) {
return path.normalize(path.join(objDirectory, mtlPath));
}

function outsideDirectory(filePath, objPath) {
return (path.relative(path.dirname(objPath), filePath).indexOf('..') === 0);
function outsideDirectory(file, directory) {
return (path.relative(directory, file).indexOf('..') === 0);
}

function loadMaterials(mtlPaths, objPath, options) {
var secure = options.secure;
var logger = options.logger;
var objDirectory = path.dirname(objPath);
var materials = {};

Expand All @@ -480,39 +478,69 @@ function loadMaterials(mtlPaths, objPath, options) {

return Promise.map(mtlPaths, function(mtlPath) {
mtlPath = normalizeMtlPath(mtlPath, objDirectory);
if (secure && outsideDirectory(mtlPath, objPath)) {
logger('Could not read mtl file at ' + mtlPath + ' because it is outside of the obj directory and the secure flag is true. Using default material instead.');
return;
var shallowPath = path.join(objDirectory, path.basename(mtlPath));
if (options.secure && outsideDirectory(mtlPath, objPath)) {
// Try looking for the .mtl in the same directory as the obj
optionslogger('The material file is outside of the obj directory and the secure flag is true. Attempting to read the material file from within the obj directory instead.');
return loadMtl(shallowPath)
.then(function(materialsInMtl) {
Object.assign(materials, materialsInMtl);
})
.catch(function(error) {
console.logger(error.message);
console.logger('Could not read material file at ' + shallowPath + '. Using default material instead.');
});
}
return loadMtl(mtlPath)
.catch(function(error) {
// Try looking for the .mtl in the same directory as the obj
options.logger(error.message);
options.logger('Could not read material file at ' + mtlPath + '. Attempting to read the material file from within the obj directory instead.');
return loadMtl(shallowPath);
})
.then(function(materialsInMtl) {
materials = Object.assign(materials, materialsInMtl);
Object.assign(materials, materialsInMtl);
})
.catch(function() {
logger('Could not read mtl file at ' + mtlPath + '. Using default material instead.');
.catch(function(error) {
options.logger(error.message);
options.logger('Could not read material file at ' + shallowPath + '. Using default material instead.');
});
}, {concurrency : 10})
.thenReturn(materials);
.then(function() {
return materials;
});
}

function loadImages(imagePaths, objPath, options) {
var secure = options.secure;
var logger = options.logger;
var images = {};
var objDirectory = path.dirname(objPath);
return Promise.map(imagePaths, function(imagePath) {
if (secure && outsideDirectory(imagePath, objPath)) {
logger('Could not read image file at ' + imagePath + ' because it is outside of the obj directory and the secure flag is true. Material will ignore this image.');
return;
var shallowPath = path.join(objDirectory, path.basename(imagePath));
if (options.secure && outsideDirectory(imagePath, objDirectory)) {
// Try looking for the image in the same directory as the obj
options.logger('Image file is outside of the obj directory and the secure flag is true. Attempting to read the image file from within the obj directory instead.');
return loadImage(shallowPath, options)
.catch(function(error) {
options.logger(error.message);
options.logger('Could not read image file at ' + shallowPath + '. This image will be ignored');
});
} else {
return loadImage(imagePath, options)
.catch(function(error) {
// Try looking for the image in the same directory as the obj
options.logger(error.message);
options.logger('Could not read image file at ' + imagePath + '. Attempting to read the image file from within the obj directory instead.');
return loadImage(shallowPath, options);
})
.catch(function(error) {
options.logger(error.message);
options.logger('Could not read image file at ' + shallowPath + '. This image will be ignored.');
});
}
return loadImage(imagePath, options)
.then(function(image) {
images[imagePath] = image;
})
.catch(function() {
logger('Could not read image file at ' + imagePath + '. Material will ignore this image.');
});
}, {concurrency : 10})
.thenReturn(images);
.then(function(images) {
return images;
});
}

function getImagePaths(materials) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Blender MTL File: 'box.blend'
# Material Count: 1

newmtl MaterialTextured
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd ../box-textured/cesium.png
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Blender v2.78 (sub 0) OBJ File: 'box-multiple-materials.blend'
# www.blender.org
mtllib box-external-resources-in-root.mtl
mtllib ../box/box.mtl
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
usemtl MaterialTextured
f 3/1/1 7/2/1 5/3/1 1/4/1
f 1/9/3 2/10/3 4/11/3 3/12/3
f 3/1/5 4/6/5 8/17/5 7/18/5
usemtl Material
f 8/5/2 4/6/2 2/7/2 6/8/2
f 7/13/4 8/14/4 6/15/4 5/16/4
f 5/19/6 6/20/6 2/7/6 1/4/6
12 changes: 12 additions & 0 deletions specs/data/box-external-resources-in-root/box.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Blender MTL File: 'None'
# Material Count: 1

newmtl Material
Ns 96.078431
Ka 0.100000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.100000
Ni 1.000000
d 1.000000
illum 2
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions specs/data/box-resources-in-root/box-resources-in-root.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Blender MTL File: 'box.blend'
# Material Count: 1

newmtl Material
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd resources/textures/cesium.png
46 changes: 46 additions & 0 deletions specs/data/box-resources-in-root/box-resources-in-root.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Blender v2.78 (sub 0) OBJ File: 'box.blend'
# www.blender.org
mtllib resources/box-resources-in-root.mtl
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 0.0000 0.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 1.0000
vt 1.0000 0.0000
vt 1.0000 1.0000
vt 0.0000 0.0000
vt 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/5/2 4/6/2 8/7/2 7/8/2
f 7/9/3 8/10/3 6/11/3 5/12/3
f 5/13/4 6/14/4 2/15/4 1/16/4
f 3/5/5 7/17/5 5/18/5 1/16/5
f 8/19/6 4/6/6 2/15/6 6/20/6
Binary file added specs/data/box-resources-in-root/cesium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 31 additions & 4 deletions specs/lib/loadObjSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ var objMtllibSpacesUrl = 'specs/data/box-mtllib-spaces/box mtllib.obj';
var objMissingMtllibUrl = 'specs/data/box-missing-mtllib/box-missing-mtllib.obj';
var objMissingUsemtlUrl = 'specs/data/box-missing-usemtl/box-missing-usemtl.obj';
var objExternalResourcesUrl = 'specs/data/box-external-resources/box-external-resources.obj';
var objResourcesInRootUrl = 'specs/data/box-resources-in-root/box-resources-in-root.obj';
var objExternalResourcesInRootUrl = 'specs/data/box-external-resources-in-root/box-external-resources-in-root.obj';
var objTexturedUrl = 'specs/data/box-textured/box-textured.obj';
var objMissingTextureUrl = 'specs/data/box-missing-texture/box-missing-texture.obj';
var objSubdirectoriesUrl = 'specs/data/box-subdirectories/box-textured.obj';
Expand Down Expand Up @@ -329,7 +331,10 @@ describe('loadObj', function() {
expect(loadObj(objMissingMtllibUrl, defaultOptions)
.then(function(data) {
expect(data.materials).toEqual({});
expect(console.log.calls.argsFor(0)[0].indexOf('Could not read mtl file') >= 0).toBe(true);
expect(spy.calls.argsFor(0)[0].indexOf('ENOENT') >= 0).toBe(true);
expect(spy.calls.argsFor(1)[0].indexOf('Attempting to read the material file from within the obj directory instead.') >= 0).toBe(true);
expect(spy.calls.argsFor(2)[0].indexOf('ENOENT') >= 0).toBe(true);
expect(spy.calls.argsFor(3)[0].indexOf('Could not read material file') >= 0).toBe(true);
}), done).toResolve();
});

Expand Down Expand Up @@ -360,8 +365,27 @@ describe('loadObj', function() {
expect(data.images[imagePath]).toBeUndefined();
expect(data.materials.MaterialTextured).toBeDefined();
expect(data.materials.Material).toBeUndefined(); // Not in directory, so not included
expect(console.log.calls.argsFor(0)[0].indexOf('Could not read mtl file') >= 0).toBe(true);
expect(console.log.calls.argsFor(1)[0].indexOf('Could not read image file') >= 0).toBe(true);
expect(spy.calls.argsFor(0)[0].indexOf('The material file is outside of the obj directory and the secure flag is true. Attempting to read the material file from within the obj directory instead.') >= 0).toBe(true);
expect(spy.calls.argsFor(1)[0].indexOf('ENOENT') >= 0).toBe(true);
expect(spy.calls.argsFor(2)[0].indexOf('Could not read material file') >= 0).toBe(true);
}), done).toResolve();
});

it('loads resources from root directory when the .mtl path does not exist', function(done) {
expect(loadObj(objResourcesInRootUrl, options)
.then(function(data) {
expect(data.materials['Material'].diffuseTexture.source).toBeDefined();
expect(diffuseTexture.source).toBeDefined();
}), done).toResolve();
});

it('loads resources from root directory when the .mtl path is outside of the obj directory and secure is true', function(done) {
options.secure = true;
expect(loadObj(objExternalResourcesInRootUrl, options)
.then(function(data) {
var materials = data.materials;
expect(Object.keys(materials).length).toBe(2);
expect(materials['MaterialTextured'].diffuseTexture.source).toBeDefined();
}), done).toResolve();
});

Expand All @@ -380,7 +404,10 @@ describe('loadObj', function() {
var imagePath = getImagePath(objMissingTextureUrl, 'cesium.png');
expect(data.images[imagePath]).toBeUndefined();
expect(data.materials.Material.diffuseTexture).toEqual(imagePath);
expect(console.log.calls.argsFor(0)[0].indexOf('Could not read image file') >= 0).toBe(true);
expect(spy.calls.argsFor(0)[0].indexOf('ENOENT') >= 0).toBe(true);
expect(spy.calls.argsFor(1)[0].indexOf('Attempting to read the image file from within the obj directory instead.') >= 0).toBe(true);
expect(spy.calls.argsFor(2)[0].indexOf('ENOENT') >= 0).toBe(true);
expect(spy.calls.argsFor(3)[0].indexOf('Could not read image file') >= 0).toBe(true);
}), done).toResolve();
});

Expand Down

0 comments on commit 96154b5

Please sign in to comment.