Keywords: bundled, materials, local
Summary
This example shows how to create "bundled objects", which are folders that contain geometry and all the material and maps (material, texture, etc.). This approach allows collections of fully attributed objects to be created that can be injected into scenes without any need to manually merge material properties.
Important
|
This demo uses material and texture maps that are defined in the material database file, and the Material Database Editor does not understand how to handle these (yet). If you open and save the various material files used in this demo, these map configurations will be lost. These material configurations must be manually edited at this time. |
Related Materials
Details
The introduction of "bundled objects" in DIRSIG 4.7 was an effort to help users streamline the creation, use and reuse of attributed scene objects. The concept is to encapsulate a fully attributed object (the geometry, the materials, the material optical properties, attribution maps, etc.) in a carefully constructed folder. That folder is not dependent on anything outside of the folder and it can be inserted into a scene without needing to do anything other than instance the GLIST file contained in the folder.
This capability became possible because of the following changes made under the hood in DIRSIG 4.7:
-
The ability to use alphanumeric labels (formerly called "IDs" when they were limited to numeric values).
-
The ability to setup most maps in the material file rather than in the scene file.
-
The ability to specify "local materials" in the GLIST file, which takes precedence over the local materials defined in a parent GLIST file (if the GLIST file is instanced) and ultimately the scene level material file.
The following GLIST snippet shows where the ability to define "local materials" is configured:
<object search_paths="local">
<localmaterials>example.mat</localmaterials>
<basegeometry>
...
</basegeometry>
...
</object>
The first piece of the puzzle is the new <localmaterials>
element, which
specifies the name of a material file to be used with this object. In this
small example, we have specified the filename example.mat
. By default,
this filename will be looked for relative to the simulation run folder.
In addition, the default location to look for all the map images and
optical property files will default to the search paths defined in
the top-level .scene
file. However, the point of this demo is to
encapsulate the geometry and the materials in a single folder. Hence,
the new search_paths
attribute in the <object>
element in the GLIST
file was added. It has two possible values:
scene
-
This is the default (used if the attribute is not present). It indicates relative filenames will be found using the geometry and material search paths defined in the parent
.scene
file. local
-
This indicates that relative filenames are assumed to be relative to the folder containing the GLIST file.
In this demo, we are using the local
option which allows all the
material properties to be stored and located at run-time from a single
folder.
Important Files
Top-Level GLIST File
This scene is composed of two objects: a car and a parking lot. These
two objects are brought together into the scene in the main GLIST file
(see geometry/demo.glist
):
<geometrylist>
<object enabled="true">
<basegeometry>
<glist>
<filename>bundles/parking_lot/parking_lot.glist</filename>
</glist>
</basegeometry>
<staticinstance name="lot"/>
</object>
<object enabled="true">
<basegeometry>
<glist>
<filename>bundles/infiniti_g35/infiniti_g35.glist</filename>
</glist>
</basegeometry>
<staticinstance name="car">
<translation>
<point><x>-2.6</x><y>3.1</y><z>0.0</z></point>
</translation>
<rotation units="degrees" rotationorder="xyz">
<cartesiantriple><x>0</x><y>0</y><z>-90</z></cartesiantriple>
</rotation>
</staticinstance>
</object>
</geometrylist>
So far this looks an ordinary GLIST file that instances two other GLIST
files (one for the parking lot and one for the car). The special stuff
happens in those GLIST files we placed in the geometry/bundles
folder.
Note
|
We have been using the subfolder bundles as a special place for
keeping these bundled objects in our scenes. This alerts us to the
fact that these object use their own materials. Using a separate
subfolder is simply a recommendation and not a requirement.
|
Let’s look at what that geometry/bundles
folder looks like:
geometry/bundles geometry/bundles/infiniti_g35 geometry/bundles/infiniti_g35/infiniti_g35.glist geometry/bundles/infiniti_g35/infiniti_g35.mat geometry/bundles/infiniti_g35/infiniti_g35.obj geometry/bundles/infiniti_g35/materials geometry/bundles/infiniti_g35/materials/blue.ems geometry/bundles/infiniti_g35/materials/glass.ext geometry/bundles/infiniti_g35/materials/glass_brdf.ems geometry/bundles/infiniti_g35/materials/glass_brdf.fit geometry/bundles/infiniti_g35/materials/gloss.fit geometry/bundles/infiniti_g35/materials/tire_black.ems geometry/bundles/infiniti_g35/materials/vinyl_tan.ems geometry/bundles/parking_lot geometry/bundles/parking_lot/1x1.obj geometry/bundles/parking_lot/maps geometry/bundles/parking_lot/maps/lines_texture.jpg geometry/bundles/parking_lot/maps/parking_material.jpg geometry/bundles/parking_lot/maps/parking_texture.jpg geometry/bundles/parking_lot/materials geometry/bundles/parking_lot/materials/asphalt_mixed.ems geometry/bundles/parking_lot/materials/white.ems geometry/bundles/parking_lot/parking_lot.glist geometry/bundles/parking_lot/parking_lot.mat
Upon examination, we can see that there are two subfolders
(geometry/bundles/infiniti_g35
and geometry/bundles/parking_lot
)
and within each of those we see the following:
-
A
.glist
file bearing the same name as the bundle. -
A
.mat
file bearing the same name as the bundle. -
A
materials
folder containing optical properties defined in the material database file. -
An (optional)
maps
folder to store images used to drive maps.
Note
|
The name of the .glist file, the name and relative location of the
.mat file and the relative location of the optical property input
files are not part of a formal organizational standard. As long as
the filenames are correctly specified in their respective locations,
the user can choose to organize the files within the bundle folder
in whatever way the like.
|
The Parking Lot Bundle
The folder geometry/bundles/parking_lot
contains our parking lot
geometry, materials and maps. The key entry point for using this
bundled object is the parking_lot.glist
file shown below:
<geometrylist>
<object search_paths="local">
<localmaterials>parking_lot.mat</localmaterials>
<basegeometry>
<obj swapyz="false">
<filename>1x1.obj</filename>
<assign id="1">panel</assign>
</obj>
</basegeometry>
<staticinstance>
<scale>
<cartesiantriple><x>44.65</x><y>30.14</y><z>1.0</z></cartesiantriple>
</scale>
</staticinstance>
</object>
</geometrylist>
The 1x1.obj
file describes a 4-sided polygon that is 1m x 1m and centered
about the origin. The <assign>
element says to attribute all the
polygons (there is only 1 in this case) with material label (ID) 1
.
The instancing scale increases the size of the 1m x 1m polygon to 44.65m
x 30.14m.
The <localmaterials>
element says to use the file parking_lot.mat
to
find material descriptions for the labels attributed to the geometry (in
this case we only have a single label, 1
). The search_paths
attribute
in the <object>
has been set to local
, which means that it will look
for parking_lot.mat
relative to the location of parking_lot.glist
, or
in geometry/bundles/parking_lot
.
Note
|
If the local material file was materials/parking_lot.mat it would
look for it in geometry/bundles/parking_lot/materials .
|
If we look inside geometry/bundles/parking_lot/parking_lot.mat
, we will
find that the material we are looking for (label = 1
) is defined. In
this case, we have a material map that will remap hits on that geometry
to either material 2
or 3
(see the LUT
section below). The image
used to drive this mapping is specified as maps/parking_material.jpg
and
since we are using local search paths, it is assumed this file will be
geometry/bundles/parking_lot/maps/parking_material.jpg
.
MATERIAL_ENTRY { ID = 1 NAME = Parking lot, base (remapped) DOUBLE_SIDED = TRUE MATERIAL_MAP { NAME = Terrain Map ENABLED = TRUE IMAGE_FILENAME = maps/parking_material.jpg UV_PROJECTOR { ORIGIN = CARTESIAN FLIPX = FALSE FLIPY = FALSE EXTENDX = MIRROR EXTENDY = MIRROR } LUT { 0:2 255:3 } OPTIONS { ENABLE_MIXING = FALSE } } }
Note
|
Since this material is simply remapping to other materials, it doesn’t need temperature solver, radiometry solver or properties. |
The two remapped materials are defined in the rest of the parking_lot.mat
file. Each material employs a texture map with the Classic Emissivity
optical property. The location of the input emissivity and texture map
image files are also assumed to be relative to the GLIST file. In our
usage, we have chosen to place all the emissivity, extinction, BRDF, etc
files in a materials
subfolder inside the bundle. The texture map
image file is in the maps
subfolder inside the bundle.
MATERIAL_ENTRY { ID = 2 NAME = Roadway Surfaces, Asphalt, Old, Gray EDITOR_COLOR = 0.500008, 0.500008, 0.500008 DOUBLE_SIDED = TRUE RAD_SOLVER_NAME = Simple RAD_SOLVER { QUALITY = LOW } TEMP_SOLVER_NAME = Therm TEMP_SOLVER { SPECIFIC_HEAT = 0.16 MASS_DENSITY = 1.6 THERMAL_CONDUCTIVITY = 8.17 SOLAR_ABSORPTION = -1 THERMAL_EMISSIVITY = 0.94 EXPOSED_AREA = 0.4 THICKNESS = 7 } SURFACE_PROPERTIES { EMISSIVITY_PROP_NAME = ClassicEmissivity EMISSIVITY_PROP { FILENAME = materials/asphalt_mixed.ems SPECULAR_FRACTION = 0 TEXTURE_MAP { IMAGE_LIST { IMAGE { FILENAME = maps/parking_texture.jpg MIN_WAVELENGTH = 0.4 MAX_WAVELENGTH = 0.7 } } UV_PROJECTOR { ORIGIN = IMAGE FLIPX = FALSE FLIPY = FALSE EXTENDX = MIRROR EXTENDY = MIRROR } } } } }
MATERIAL_ENTRY { ID = 3 NAME = Roadway Surfaces, Asphalt, Old, Gray, lines EDITOR_COLOR = 1, 1, 1 DOUBLE_SIDED = TRUE RAD_SOLVER_NAME = Simple RAD_SOLVER { QUALITY = LOW } TEMP_SOLVER_NAME = Therm TEMP_SOLVER { SPECIFIC_HEAT = 0.465 MASS_DENSITY = 1 THERMAL_CONDUCTIVITY = 20.93 SOLAR_ABSORPTION = -1 THERMAL_EMISSIVITY = 0.75 EXPOSED_AREA = -0.34 THICKNESS = 10 } SURFACE_PROPERTIES { EMISSIVITY_PROP_NAME = ClassicEmissivity EMISSIVITY_PROP { FILENAME = materials/white.ems SPECULAR_FRACTION = 0 TEXTURE_MAP { IMAGE_LIST { IMAGE { FILENAME = maps/lines_texture.jpg MIN_WAVELENGTH = 0.4 MAX_WAVELENGTH = 0.7 STATS = 150,30 } } UV_PROJECTOR { ORIGIN = IMAGE FLIPX = FALSE FLIPY = FALSE EXTENDX = MIRROR EXTENDY = MIRROR } } } } }
The key takeaway of this example is that because we use local materials
and local search paths, the parking_lot
folder can be relocated anywhere.
As soon as the parking_lot/parking_lot.glist
file is instanced, it will
find all the supporting material files by searching relative to the
location of that file.
The Infinity G35 Bundle
The folder geometry/bundles/infiniti_g35
contains our Infinity G35 car
geometry and materials. The key entry point for using this bundled object
is the infiniti_g35.glist
file shown below:
<geometrylist>
<object search_paths="local">
<localmaterials>infiniti_g35.mat</localmaterials>
<basegeometry>
<obj swapyz="false">
<filename>infiniti_g35.obj</filename>
<assign name="paint" id="1">default</assign>
<assign id="2">windows</assign>
<assign id="2">headlights</assign>
<assign id="2">taillights</assign>
<assign id="3">grill</assign>
<assign id="3">rims</assign>
<assign id="3">sideview</assign>
<assign id="4">tires</assign>
<assign id="4">wipers</assign>
<assign id="5">interior</assign>
<assign id="5">seats</assign>
</obj>
</basegeometry>
<staticinstance/>
</object>
</geometrylist>
Once again, we are using local materials and local search paths. The
various <assign>
elements allow us to map the usemtl
assignments in
the infiniti_g35.obj
to DIRSIG material labels (IDs). Consider the
following material assignments in the OBJ file:
... g brakelight usemtl 40100 f 7914/24181/7819 7915/24182/7820 7916/24183/7821 ...
The OBJ file defines a group with the name "brakelight" which is assigned
a material with the name "40100". The group name tells us that this
geometry group is most likely the brakelight(s). Normally the name
supplied to the usemtl
will be used to find a material in the DIRSIG
material file with the same label (ID). However, the
<assign name="paint" id="1">default</assign>
entry in the GLIST says we will default all usemtl
mappings to material
label (ID) 1
. The remaining <assign>
entries can change that default
to a specific material. However, since we don’t see "40100" in those
<assign>
entries, we can assume that this geometry will get mapped
to label (ID) 1
, which is the body paint (we essentially change the
brakelights to more body).
Now consider this group in the OBJ file:
... g grill usemtl grill f 9692/29696/0 9693/29697/0 9694/29698/0 ...
The GLIST includes <assign id="3">grill</assign>
, which says that the
"grill" material will get mapped to label (ID) 3
in the material file,
which is "chrome like" material. Had this <assign>
not been present,
the grill would have defaulted to the body pint (material 1
). Note
that in this case the group name in the geometry is the same as the
material name, but as we saw before that is not always the case. The
<assign>
entries define how usemtl
entries will be mapped to DIRSIG
materials and not how to assign materials to a group (part).
Note
|
This <assign> mechanism was original introduced in DIRSIG 4.6 as
a way to map alphanumeric (and potentially terse) material names
provided to usemtl entries to the numeric-only material IDs used
in DIRSIG at the time. For example, usemtl PART000_MATERIAL4325 in
the OBJ could get mapped to ID = 11 in the DIRSIG material file.
As of DIRSIG 4.7, these labels can be alphanumeric (but cannot
contain whitespace), which means this mapping in the GLIST is
optional. For example, just make your material file have
ID = PART000_MATERIAL4325 . However, this "default plus
specific remapping" mechanism can still be very useful.
|
The material file for this object is not as interesting as the parking lot because there are not any material or texture maps.
Note
|
The material labels (IDs) being used in the infiniti_g35 bundle
(1-5) include some of the same used in the parking_lot bundle
(which used 1-3). Since the material labels are local to the
bundles, there is no need to plan, define and manage a global
material index.
|
Scene Level Materials
The scene level (top-level) demo.mat
materials file referenced in the
demo.scene
file is located in the top-level materials
file. However,
since all the materials are defined in the various bundles, there is
no need to define any materials at the scene level. However, DIRSIG
currently still requires a scene level materials file and the material
file reader will throw an error if the file is empty. Hence, the file
defines a simple, dummy material to satisfy these requirements:
MATERIAL_ENTRY { ID = 99999 NAME = Dummy EDITOR_COLOR = 0, 0, 0 }
Setup
To run the simulation, perform the following steps:
-
Run the DIRSIG
demo.sim
file -
Load the resulting
demo.img
radiance file in the image viewer.
Results
In order to help the user understand and resolve materials that are defined in multiple locations within a scene, a pair of tools are provided to the user. The first is a table included in the start-up output when the simulation runs. The table shows the mapping of the material indexes (used in the material truth) to the labels and names of materials. The text below shows the output for this simulation:
Material Index Table: 1 -> Parking lot, base (remapped) (ID/Label = 1) 2 -> Roadway Surfaces, Asphalt, Old, Gray (ID/Label = 2) 3 -> Roadway Surfaces, Asphalt, Old, Gray, lines (ID/Label = 3) 4 -> Gloss paint, blue (ID/Label = 1) 5 -> Glass (ID/Label = 2) 6 -> Chrome (ID/Label = 3) 7 -> Tire, Rubber, Black, Fair (ID/Label = 4) 8 -> Vinyl, tan (ID/Label = 5)
The second is a new material summary report (see the file
material_report.json
), which includes the same mapping info as the
start-up output but also includes the path to the material that material
was defined in. The file produced for this simulation shows the labels
and names for the materials used in the respective parking lot and
car bundles:
{
"info": {
"created": "2023-12-18 08:18:31",
"file_type": "Material Report",
"generator": "scene2hdf",
"version": "2023.50 (7a89f9a)"
},
"materials": {
"bundles": [
{
"filename": "/Users/demos/BundledObject1/geometry/bundles/infiniti_g35/infiniti_g35.glist",
"materials": {
"1": {
"materialIndex": 4,
"name": "Gloss paint, blue (id = 1)"
},
"2": {
"materialIndex": 5,
"name": "Glass (id = 2)"
},
"3": {
"materialIndex": 6,
"name": "Chrome (id = 3)"
},
"4": {
"materialIndex": 7,
"name": "Tire, Rubber, Black, Fair (id = 4)"
},
"5": {
"materialIndex": 8,
"name": "Vinyl, tan (id = 5)"
}
},
"objectIndex": 0
},
{
"filename": "/Users/demos/BundledObject1/geometry/bundles/parking_lot/parking_lot.glist",
"materials": {
"1": {
"materialIndex": 3,
"name": "Parking lot, base (remapped) (id = 1)"
},
"2": {
"materialIndex": 1,
"name": "Roadway Surfaces, Asphalt, Old, Gray (id = 2)"
},
"3": {
"materialIndex": 2,
"name": "Roadway Surfaces, Asphalt, Old, Gray, lines (id = 3)"
}
},
"objectIndex": 0
}
],
"scene": {}
}
}
Note
|
Again, notice that the material labels (IDs) being used in the
infiniti_g35 bundle (1-5) include some of the same used in the
parking_lot bundle (which used 1-3). This table helps the user
map the global material indexes reported in the material truth
back to the local material labels (IDs) and which material file
those materials are defined in.
|
The image below shows the output of the simulation: