Function Repository Resource:

ImportMTL

Source Notebook

Import a Wavefront Material Template Library file as a labeled set of graphics directives

Contributed by: Kevin Daily

ResourceFunction["ImportMTL"][source]

imports the MTL data from source, returning a labeled set of Graphics3D directives.

ResourceFunction["ImportMTL"]["mtl"]

reads the string "mtl" as MTL data.

ResourceFunction["ImportMTL"][source,element]

imports the specified element of the source.

Details and Options

The MTL format is a human-readable ASCII text file.
ImportMTL uses Import to first load the data from source as "Text", then parses the text for any materials.
The ImportMTL source supports all of the same first arguments as Import.
If the source file cannot be located, then ImportMTL parses a string as if it were MTL data.
Elements supported by ImportMTL include:
"Elements"a list of supported element names
"Text"the raw text from the file including any comments
"Data"an Association of the data's key-value pairs where key's are all lowercase
"Dataset"same as "Data" but viewed as a Dataset
"Directive"(default) a set of Graphics3D directives
MTL color parameters are either RGBColor or XYZColor without an AlphaChannel and map to the following Directive expressions:
"ka"AmbientLight[color]
"kd"FaceForm[color]
"ke"Glow[color]
"ks"Specularity[color]
The emission color "ke" is not part of the original MTL specification but supported by some 3D software.
A texture map can be specified for the diffuse color and maps to the following Directive expression:
"map_kd"Texture[image]
MTL scalar parameters are a single numerical value and map to the following Directive expressions:
"d"Opacity[val]
"ns"Specularity[,val]
"tr"Opacity[1-val]
The transparency "tr" is not part of the original MTL specification but included as a convenience and is opposite in value to the dissolve property "d".
The illumination model "illum" has 10 possible integer values but only the first three are representable in Graphics3D:
The extended MTL specification provides attributes for physically-based rendering and includes the following additional parameters and colors:
"aniso"MaterialShading[,"SpecularAnisotropyCoefficient"val,]
"anisor"MaterialShading[,"SpecularAnisotropyCoefficient"{,val},]
"ke"MaterialShading[,"EmissionColor"color,]
"pm"MaterialShading[,"MetallicCoefficient"val,]
"pr"MaterialShading[,"RoughnessCoefficient"val,]
"ps"MaterialShading[,"SheenColor"color,]
The following texture maps are also possible using MaterialShading:
"map_ka"MaterialShading[,"AmbientExposureFraction"Texture[image],]
"map_kd"MaterialShading[,"BaseColor"Texture[image],]
"map_ke"MaterialShading[,"EmissionColor"Texture[image],]
"map_ks"MaterialShading[,"SpecularColor"Texture[image],]
"map_pm"MaterialShading[,"MetallicCoefficient"Texture[image],]
"map_pr"MaterialShading[,"RoughnessCoefficient"Texture[image],]
"norm"MaterialShading[,"SurfaceNormals"Texture[image],]
Color maps include "map_kd", "map_ke", and "map_ks".
Parameter maps include "map_ka", "map_pm", and "map_pr".
The color maps are expected to be images in the RGB or XYZ color space.
The parameter maps are expected to be images in the Grayscale color space and act as an intensity map or image mask.
If a texture map in the RGBA or XYZA color space is provided for a parameter texture map then only the AlphaChannel is used.
The "norm" maps an image but the color channels are interpreted as vector coordinates.
If both a texture map and a corresponding color or parameter are specified, the texture map is multiplied by the corresponding color or parameter.
For example, if "kd" and "map_kd" are provided, the resulting texture is Texture[ImageMultiply[image,color]].
ImportMTL uses the following option:
"BaseDirectory"Automaticthe file path used to find texture map files
Possible settings for "BaseDirectory" are:
Automaticuse the directory where the.mtl file resides
"path"use the provided directory path
If a verbose path is used for "BaseDirectory", then only the filename of a texture map is used to resolve the full path.

Examples

Basic Examples (7) 

Import a basic material:

In[1]:=
ResourceFunction["ImportMTL"]["
newmtl example
Kd 1.0 0 0
Ke 0 1.0 0
d 0.9
illum 2"]
Out[1]=

To import a basic material that includes a texture map you must first have the texture file locally on your machine:

In[2]:=
(* example texture map *)
Export["example_base.png", RandomImage[{0, 1}, ColorSpace -> "RGB"]]
Out[2]=

Then ImportMTL can include the texture data:

In[3]:=
ResourceFunction["ImportMTL"]["
newmtl example
map_kd example_base.png
illum 2"]
Out[3]=

Import MTL data that was stored via CloudPut:

In[4]:=
ResourceFunction["ImportMTL"][
CloudObject[
 "https://www.wolframcloud.com/obj/kevind/WFR/example_mtl_1"]]
Out[4]=

Import an MTL file stored as a CloudObject:

In[5]:=
ResourceFunction["ImportMTL"][
CloudObject["https://www.wolframcloud.com/obj/kevind/WFR/example.mtl"]
 ]
Out[5]=

An MTL file stored as a CloudObject may reference a texture map file:

In[6]:=
cloudRoot = CloudObject["https://www.wolframcloud.com/obj/kevind/WFR"];
StringCases[CloudImport[FileNameJoin[{cloudRoot, "example_2.mtl"}]], StartOfLine ~~ "map" ~~ __ ~~ EndOfLine]
Out[7]=

The texture map is automatically found if the texture file is located in the same CloudDirectory as the MTL file:

In[8]:=
ResourceFunction["ImportMTL"][
 FileNameJoin[{cloudRoot, "example_2.mtl"}]]
Out[8]=

Import a MTL file from a URL:

In[9]:=
urlBase = "https://raw.githubusercontent.com/KMDaily/WolframExamples/main";
ResourceFunction["ImportMTL"][
 URLBuild[{urlBase, "example_mtl_1.mtl"}]]
Out[10]=

An MTL file stored at a URL may reference a texture map file:

In[11]:=
urlBase = "https://raw.githubusercontent.com/KMDaily/WolframExamples/main";
StringCases[Import[URLBuild[{urlBase, "example_mtl_2.mtl"}], "Text"], StartOfLine ~~ "map" ~~ __ ~~ EndOfLine]
Out[12]=

The texture map is automatically found if the texture file is located in the same URL base as the MTL file:

In[13]:=
ResourceFunction["ImportMTL"][
 URLBuild[{urlBase, "example_mtl_2.mtl"}]]
Out[13]=

Scope (6) 

Import the material data as plain text:

In[14]:=
ResourceFunction[
 "ImportMTL"]["newmtl example\nKd 1.0 0 0\nKe 0 1.0 0\nd 0.9\nillum 2", "Text"]
Out[14]=

Import the material data as an Association:

In[15]:=
ResourceFunction[
 "ImportMTL"]["newmtl example\nKd 1.0 0 0\nKe 0 1.0 0\nd 0.9\nillum 2", "Data"]
Out[15]=

Import the material data as a Dataset:

In[16]:=
ResourceFunction[
 "ImportMTL"]["newmtl example\nKd 1.0 0 0\nKe 0 1.0 0\nd 0.9\nillum 2", "Dataset"]
Out[16]=

Import a material that uses extensions to the original MTL specification:

In[17]:=
ResourceFunction["ImportMTL"]["
newmtl example
Kd 1.0 0 0
Ps 0 0 1.0
Pr 0.5
Ks 0 1.0 0
Ns 100
illum 2"]
Out[17]=

Use an imported basic material in Graphics3D:

In[18]:=
Row[{#, Graphics3D[Append[#[[1]], Sphere[]]]}] &[
 ResourceFunction["ImportMTL"][
  "newmtl example\nKd 1.0 0 0\nKs 0 1.0 0\nNs 100\nillum 2"]]
Out[18]=

Import a material that resolves to MaterialShading:

In[19]:=
mtldata = ResourceFunction["ImportMTL"][
  "newmtl example\nKd 1.0 0 0\nPm 0.2\nPs 0 0 1.0\nPr 0.5\nKs 0 1.0 0\nNs 100\nillum 2"]
Out[19]=

Use in Graphics3D:

In[20]:=
Graphics3D[Append[First@mtldata, Sphere[]], Lighting -> "ThreePoint"]
Out[20]=

Options (3) 

BaseDirectory (3) 

Create paths for a base directory and files:

In[21]:=
base = $TemporaryDirectory;
mtlFile = FileNameJoin[{base, "example.mtl"}];
redTexture = FileNameJoin[{base, "example_base.png"}];
blueTexture = FileNameJoin[{base, "tex", "example_base.png"}];

Populate this base directory with files to import:

In[22]:=
Export[mtlFile, "newmtl example\nmap_kd example_base.png\nillum 2", "Text"];
Export[redTexture, ConstantImage[Red]];
Export[blueTexture, ConstantImage[Blue]];

Specifically search the "tex" subdirectory to find the blue texture instead of the red texture:

In[23]:=
ResourceFunction["ImportMTL"][mtlFile, "BaseDirectory" -> FileNameJoin[{FileNameDrop[mtlFile], "tex"}]]
Out[23]=

Possible Issues (3) 

It is not guaranteed that the MTL files downloaded from the internet use relative paths for textures or match the $PathnameSeparator for your operating system:

In[24]:=
mtlFile = FileNameJoin[{$TemporaryDirectory, "example.mtl"}];
redTexture = FileNameJoin[{$TemporaryDirectory, "example_base.png"}];
Export[mtlFile, "newmtl example\nmap_kd C:\\Downloads\\example_base.png\nillum 2", "Text"];
Export[redTexture, ConstantImage[Red]];

Attempting to import the MTL file will not be able to locate the referenced texture file:

In[25]:=
ResourceFunction["ImportMTL"][mtlFile]
Out[25]=

Specify the directory where the files reside to override the default behavior:

In[26]:=
ResourceFunction["ImportMTL"][mtlFile, "BaseDirectory" -> FileNameDrop[mtlFile]]
Out[26]=

Publisher

Kevin Daily

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.0 – 09 August 2023

Source Metadata

Related Resources

Author Notes

Though it was part of the original specification, almost no external software uses the XYZ color space.

License Information