Commit 35a406a3 authored by PACANOWSKI Romain's avatar PACANOWSKI Romain
Browse files

Merge branch 'dmu_indexed_material' into 'master'

Indexed material

See merge request !214
parents 8940a723 b70ea39b
Pipeline #261548 failed with stages
in 28 minutes and 11 seconds
......@@ -155,6 +155,12 @@ endif()
if (ENABLE_TEST)
add_subdirectory(unit_tests)
message("Adding Test for mrf/image_laplacian_filling Module")
compile_named_test( image_laplacian_filling ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests/image_laplacian_filling/main.cpp )
message("Adding Test for mrf/brdf_slice_normalization Module")
compile_named_test( brdf_slice_normalization ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests/brdf_slice_normalization/main.cpp )
# Util module Tests
endif()
# ----------------------------------------------------------------------------
......
......@@ -568,97 +568,111 @@ _renderer.setMaxRenderingTime(max_rendering_time);
loger.info(_renderer->getInfos());
auto total_rendering_time = _renderer->renderSamples();
_renderer->enableAssetsUpdate();
//for (int env_phi = 0; env_phi < 1; ++env_phi)
{
//_renderer->setRotationPhi(env_phi);
auto total_rendering_time = _renderer->renderSamples();
//_renderer->disableAssetsUpdate();
std::string temp_file_name;
std::string temp_file_extension;
string dir;
std::string temp_file_name;
std::string temp_file_extension;
string dir;
// Sets the image output file will be overriden IF -o is passed fro mthe command line
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(
parser.getSingleValue(ARG_LIST::SCENE).c_str(),
temp_file_name);
mrf::util::StringParsing::getDirectory(parser.getSingleValue(ARG_LIST::SCENE).c_str(), dir);
// Sets the image output file will be overriden IF -o is passed fro mthe command line
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(
parser.getSingleValue(ARG_LIST::SCENE).c_str(),
temp_file_name);
mrf::util::StringParsing::getDirectory(parser.getSingleValue(ARG_LIST::SCENE).c_str(), dir);
loger.trace(" Temp file name ", temp_file_name);
loger.trace(" temp_file_extension", temp_file_extension);
loger.trace(" dir ", dir);
loger.trace(" Temp file name ", temp_file_name);
loger.trace(" temp_file_extension", temp_file_extension);
loger.trace(" dir ", dir);
//RGB rendering can save under multiples formats
#ifndef MRF_RENDERING_MODE_SPECTRAL
//multiples filename is usefull to save an image under several formats
// RP: IS this code robust when -o is not specified on the command line?
for (mrf::uint i = 0; i < parser.getMultipleValue(ARG_LIST::OUTPUT).size(); i++)
{
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(
parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(),
temp_file_name);
mrf::util::StringParsing::getFileExtension(
parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(),
temp_file_extension);
mrf::util::StringParsing::getDirectory(parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(), dir);
//multiples filename is usefull to save an image under several formats
// RP: IS this code robust when -o is not specified on the command line?
for (mrf::uint i = 0; i < parser.getMultipleValue(ARG_LIST::OUTPUT).size(); i++)
{
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(
parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(),
temp_file_name);
mrf::util::StringParsing::getFileExtension(
parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(),
temp_file_extension);
mrf::util::StringParsing::getDirectory(parser.getMultipleValue(ARG_LIST::OUTPUT)[i].c_str(), dir);
#else //spectral rendering mode
string const tmp = parser.getSingleValue(ARG_LIST::OUTPUT);
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(tmp.c_str(), temp_file_name);
loger.trace("Current output image filename is = ", temp_file_name);
string const tmp = parser.getSingleValue(ARG_LIST::OUTPUT);
mrf::util::StringParsing::fileNameFromAbsPathWithoutExtension(tmp.c_str(), temp_file_name);
loger.trace("Current output image filename is = ", temp_file_name);
mrf::util::StringParsing::getDirectory(parser.getSingleValue(ARG_LIST::OUTPUT).c_str(), dir);
mrf::util::StringParsing::getFileExtension(parser.getSingleValue(ARG_LIST::OUTPUT).c_str(), temp_file_extension);
mrf::util::StringParsing::getDirectory(parser.getSingleValue(ARG_LIST::OUTPUT).c_str(), dir);
mrf::util::StringParsing::getFileExtension(
parser.getSingleValue(ARG_LIST::OUTPUT).c_str(),
temp_file_extension);
#endif
if (temp_file_extension == "")
{
loger.warn("File extension not specified for output. Spectral with Envy Format assigned as default!");
temp_file_extension = "hdr";
}
string samples_information = "";
if (temp_file_extension == PNG_EXTENSION)
{
samples_information = "_" + std::to_string(_renderer->numSamplesPerPixel()) + "spp";
}
if (number_of_cameras > 1)
{
// Format the Ouptut filename
unsigned int const numberOfDigits
= number_of_cameras ? static_cast<unsigned int>(std::log10(number_of_cameras)) + 1 : 1;
std::stringstream ss;
ss << std::setw(numberOfDigits + 1) << std::setfill('0') << cam_index;
std::string const s = ss.str();
if (temp_file_extension == "")
{
loger.warn("File extension not specified for output. Spectral with Envy Format assigned as default!");
temp_file_extension = "hdr";
}
string samples_information = "";
if (temp_file_extension == PNG_EXTENSION)
{
samples_information = "_" + std::to_string(_renderer->numSamplesPerPixel()) + "spp";
}
//string env_info = "_envPhi";
//if(env_phi < 10) env_info += std::to_string(0);
//if(env_phi < 100) env_info += std::to_string(0);
// env_info += std::to_string(env_phi);
if (number_of_cameras > 1)
{
// Format the Ouptut filename
unsigned int const numberOfDigits
= number_of_cameras ? static_cast<unsigned int>(std::log10(number_of_cameras)) + 1 : 1;
std::stringstream ss;
ss << std::setw(numberOfDigits + 1) << std::setfill('0') << cam_index;
std::string const s = ss.str();
Camera const *current_cam = cams[cam_index];
temp_file_name = dir + ss.str() + "_" + current_cam->idName() + "_" + temp_file_name
+ samples_information
/*+ env_info*/
+ "." + temp_file_extension;
}
else
{
temp_file_name = dir + temp_file_name + samples_information /*+ env_info*/ + "." + temp_file_extension;
}
loger.trace("Current output image filename is = ", temp_file_name);
std::string comment_rendering_time
= "Total rendering time = " + std::to_string(total_rendering_time) + " s\n";
_renderer->saveImage(temp_file_name, comment_rendering_time);
Camera const *current_cam = cams[cam_index];
#ifndef MRF_RENDERING_MODE_SPECTRAL
} //endfor multiple filenames RGB mode
#endif
temp_file_name = dir + ss.str() + "_" + current_cam->idName() + "_" + temp_file_name + samples_information
+ "." + temp_file_extension;
}
else
if (logfile_stream.is_open())
{
temp_file_name = dir + temp_file_name + samples_information + "." + temp_file_extension;
logfile_stream << parser.getSingleValue(ARG_LIST::SCENE) << ", " << std::to_string(total_rendering_time)
<< "," << parser.getSingleValue(ARG_LIST::SAMPLES) << ","
<< parser.getSingleValue(ARG_LIST::SPF) << std::endl;
}
loger.trace("Current output image filename is = ", temp_file_name);
std::string comment_rendering_time
= "Total rendering time = " + std::to_string(total_rendering_time) + " s\n";
_renderer->saveImage(temp_file_name, comment_rendering_time);
#ifndef MRF_RENDERING_MODE_SPECTRAL
} //endfor multiple filenames RGB mode
#endif
if (logfile_stream.is_open())
{
logfile_stream << parser.getSingleValue(ARG_LIST::SCENE) << ", " << std::to_string(total_rendering_time)
<< "," << parser.getSingleValue(ARG_LIST::SAMPLES) << ","
<< parser.getSingleValue(ARG_LIST::SPF) << std::endl;
std::cout << "Image saved to: " << temp_file_name << std::endl;
std::cout << "Rendering Time: " << std::to_string(total_rendering_time) << " seconds" << std::endl;
}
std::cout << "Image saved to: " << temp_file_name << std::endl;
std::cout << "Rendering Time: " << std::to_string(total_rendering_time) << " seconds" << std::endl;
_renderer->nextCamera();
} //for loop on cameras
......
This diff is collapsed.
......@@ -604,6 +604,22 @@ def add_material_phong(root_node,material_name,rgb,roughness,directory_full_path
material.append(specular_xml)
materials.append(material)
def add_multi_material(root_node,material_name, multi_mat_names, multi_mat_indices, directory_full_path, directory_relative_path,mrf_tools):
print("ADD Multi Material")
materials = root_node.find('materials')
material = ET.Element('material')
material.set('name',material_name)
material.set('type','multi_material')
nb_mat = len(multi_mat_names)
for i in range(0, nb_mat):
sub_mat = ET.Element('material')
sub_mat.set('index',str(multi_mat_indices[i]))
sub_mat.set('name',str(multi_mat_names[i]))
material.append(sub_mat)
materials.append(material)
def add_point_light(root_node,power,rgb,pos,light_name,directory_full_path, directory_relative_path):
lights = root_node.find('lights')
point_light = ET.Element('point_light')
......
......@@ -47,7 +47,7 @@
<a class="current" href="./scene_format.md.html#toc3.2">Analytical BSDF</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc3.3">Measured Isotropic BRDF</a>
<a class="current" href="./scene_format.md.html#toc3.3">Measured BRDF</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc3.4">Shadow Catcher</a>
......@@ -57,23 +57,26 @@
</li>
</ul>
</li>
<li class="current toctree_l2">
<a class="current" href="./scene_format.md.html#toc4">Indexed Material</a>
</li>
<li class="current toctree_l2">
<a class="current" href="./scene_format.md.html#toc4">Light Sources</a>
<a class="current" href="./scene_format.md.html#toc5">Light Sources</a>
<ul class="current toctree_l2">
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc4.1">Point Light</a>
<a class="current" href="./scene_format.md.html#toc5.1">Point Light</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc4.2">Directional Light</a>
<a class="current" href="./scene_format.md.html#toc5.2">Directional Light</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc4.3">Background and Environment map</a>
<a class="current" href="./scene_format.md.html#toc5.3">Background and Environment map</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc4.4">Quad Light</a>
<a class="current" href="./scene_format.md.html#toc5.4">Quad Light</a>
</li>
<li class="current toctree_l3">
<a class="current" href="./scene_format.md.html#toc4.5">Sphere Light</a>
<a class="current" href="./scene_format.md.html#toc5.5">Sphere Light</a>
</li>
</ul>
</li>
......@@ -599,7 +602,14 @@ Note for both sheen and specular tint, the colored response is the achromatic ra
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
## Measured Isotropic Brdf
## Measured BRDF
Here is the list of measured BSDF supported in Malia:
- <a class="current" href="./scene_format.md.html#toc3.3.1">ALTA BRDF (isotropic)</a>
- <a class="current" href="./scene_format.md.html#toc3.3.2">UTIA BRDF</a>
### Isotropic ALTA BRDF
The Measured Isotropic material supports the loading of alta file (.bin) with a
$(\theta_{view},\theta_{light}, \Delta\phi = |\phi_{view} - \phi_{light}| )$ parametrization.
......@@ -608,14 +618,14 @@ To simplify scene authoring, both RGB and spectral data can be specify in the sa
This allows a scene to work both in rgb rendering mode and spectral rendering mode.
The xml attribute file_rgb specify the alta rgb file whereas file_spectral specify the alta spectral file.
!!! WARNING: In some scene you might find a xml attribute "file" to specify the input alta file, it overrides the "file_rgb" or "file_spectral" attribute.
You can, for instance, instantiate a Measured Isotropic material using the following code:
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<materials>
<material file="./material_export_assets/brdf_measured_RGB.bin"
<material
file_rgb="./material_export_assets/brdf_measured_RGB.bin"
file_spectral="./material_export_assets/brdf_measured_SPECTRAL.bin" name="a_measured_material"
type="MeasuredIsotropic" />
</material>
......@@ -623,7 +633,9 @@ You can, for instance, instantiate a Measured Isotropic material using the follo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
### Example of supported ALTA file
!!! WARNING: In some scene you might find a xml attribute "file" to specify the input alta file, it overrides the "file_rgb" or "file_spectral" attribute.
#### Example of supported ALTA file
An ALTA file (./material_export_assets/brdf_measured_SPECTRAL.bin in the example above) consists
of a header part that specifies and describes how the data part can be read.
......@@ -676,7 +688,7 @@ where :
### Spectral BRDF as an ALTA FILE
#### Spectral BRDF as an ALTA FILE
In the case of a spectral BRDF, the sampled wavelengths should be specified in the header by the keyword WAVELENGTH (in
nanometers):
......@@ -715,13 +727,13 @@ $number\_of\_wavelength \times number\_of\_theta\_incident$.
Note that it is also possible to specify a perfect MIRROR BRDF for RGB-BRDF (i.e., #PARAM_OUT RGB_COLOR),
the Malia parser will expect 3 values per incident angles instead of number_of_wavelength.
### Selecting Dirac or Scattering part of a measured file
<!-- ### Selecting Dirac or Scattering part of a measured file -->
By default Malia will use all parts (analytical and measured) of an alta file to generate the image.
When a measured material contains a perfect mirror (dirac) pat and a scattering part
it possible to render only the scattering part or the dirac part adding the attributes scatter_only
or dirac_only to the material markup.
<!-- When a measured material contains a perfect mirror (dirac) pat and a scattering part -->
<!-- it possible to render only the scattering part or the dirac part adding the attributes scatter_only -->
<!-- or dirac_only to the material markup. -->
Example to render only the Dirac part of the material:
<script type="preformatted">
......@@ -748,6 +760,32 @@ Example to render only the scattering part of the material:
</materials>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
### UTIA BRDF
Example of UTIA materials, both 2D (isotropic) and 4D (anisotropic):
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<materials>
<material name="a_4d_utia_material" type="UTIA" />
<utia_texture file="./path/to/texture" interpolate="1" parametrization="utia_4d">
<utia_parameters theta_i_div="9" theta_v_div="9" phi_i_div="48" phi_v_div="48" />
</utia_texture>
</material>
<material name="a_2d_utia_material" type="UTIA" />
<utia_texture file="./path/to/texture" interpolate="1" parametrization="utia_2d">
<utia_parameters theta_i_div="90" theta_v_div="90"/> #not mandatory for 2d isotropic.
</utia_texture>
</material>
</materials>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
<!-- TODO MORE DOC HERE !!! -->
## Shadow Catcher
The shadow catcher is a proxy material to project shadows on the environment. It must be use with a plane geometry.
......@@ -805,6 +843,84 @@ Note that emittance materials need to be defined inside
a light source markup (e.g., `<area_light>`, `<sphere_light>`)
# Indexed Material
A single mesh may use several materials on a per-face basis. MRF handles this situation by using a proxy material aggregating all these materials.
This proxy material is declared as:
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<material name="a_multi_mat" type="multi_material">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
All the materials must be present as sub-element of the multi-material.
There two ways of doing so. The first is to declare the materials independently (using the "material" markup and information above) and just reference them by name below the multi-material element:
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<materials>
<material name="mat1" type="diffuse">
<some markups />
</material>
<material name="mat2" type="principled">
<some markups />
</material>
<material name="a_multi_mat" type="multi_material">
<material name="mat1"/>
<material name="mat2"/>
</material>
</materials>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
It is the syntax used by our blender bridge. The order between in which the single materials and the multi-material are declared is not important.
The second is to declare the materials directly under the multi-material element:
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<materials>
<material name="a_multi_mat" type="multi_material">
<material name="mat1" type="diffuse">
<some markups />
</material>
<material name="mat2" type="PhongNormalized">
<some markups />
</material>
</material>
</materials>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
Both ways are equivalent whatever the scene configuration.
All type of materials supported by MRF are also supported as sub-elements of a multi-material.
!!! WARNING Avoid recursivity - Undefined behavior
Using a multi-material as a sub-element of another multi-material leads to undefined behavior and should be avoided.
Then only the proxy multi-material is attached to the shape:
<script type="preformatted">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<shapes>
<shape ref_material="a_multi_mat">
<mesh name="a_mesh">
<obj file="a_mesh.obj"/>
</mesh>
</shape>
</shapes>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</script>
!!! WARNING Limited support for PLY
The support of PLY must be done manually by adding a "mat_idx" property to faces elements. In that case, the materials must be referenced by the multi-material in the exact same order as their index in the PLY (e.g., in the examples above, "mat1" must correspond to material index "0" in the PLY).
If you can, prefer the OBJ mesh format, for which as long as materials have the same name in the material file and in MRF, the match between faces and materials is guaranteed regardless of the order.
!!! Note No support of RTCores
At the moment, this type of material does not exploit RTCores for ray-tracing acceleration in our implementation. If you experience slow performance, consider splitting you mesh beforehand to fall back to a collection of meshes with single material. The full support of RTCores is scheduled for a future version.
# Light sources
All the light sources are stored in the Scene object.
Several types of light sources are supported:
......
......@@ -66,8 +66,9 @@ void OptixGeometryHandler::importMrfScene(
top_group->addChild(geometry_group);
//Set up generic triangle mesh programs
//ptx = getPtxString("triangle_mesh.cu", cuda_compile_options_temp);
ptx = getPtxString("triangle_attributes.cu", cuda_compile_options);
ptx = getPtxString("triangle_mesh.cu", cuda_compile_options);
const char *tri_ptx = getPtxString("triangle_attributes.cu", cuda_compile_options);
//ptx = getPtxString("triangle_attributes.cu", cuda_compile_options);
//Create geometry group for triangle geometry (using GeometryTriangle)
optix::GeometryGroup tri_geometry_group = _context->createGeometryGroup();
......@@ -95,8 +96,7 @@ void OptixGeometryHandler::importMrfScene(
unsigned int mat_index = a_sphere->materialIndex();
_optix_analytical_shapes.push_back(std::make_pair(gi, mat_index));
// ADD MATERIAL Dummy material for now
gi->addMaterial(material_handler.lambert());
gi->addMaterial(material_handler.getMaterialFromMRF(mat_index)[0]);
//TODO UPDATE aabb ?
......@@ -119,11 +119,33 @@ void OptixGeometryHandler::importMrfScene(
uint material_id = (*shape_it)->materialIndex();
if (material_handler.needMeshRefine(material_id))
optix_mesh.attributes = _context->createProgramFromPTXString(ptx, "triangle_attributes_refine");
else
optix_mesh.attributes = _context->createProgramFromPTXString(ptx, "triangle_attributes");
std::vector<optix::Material> optix_materials = material_handler.getMaterialFromMRF(material_id);
optix::Matrix4x4 transform = optix::Matrix4x4((*shape_it)->worldToObjectTransform().ptr());
if (optix_materials.size() == 1)
{
if (material_handler.needMeshRefine(material_id))
optix_mesh.attributes = _context->createProgramFromPTXString(tri_ptx, "triangle_attributes_refine");
else
optix_mesh.attributes = _context->createProgramFromPTXString(tri_ptx, "triangle_attributes");
loadMeshFromMRF(*mrf_mesh, optix_mesh, transform, optix_materials);
tri_geometry_group->addChild(optix_mesh.geom_instance);
}
else
{
if (material_handler.needMeshRefine(material_id))
optix_mesh.intersection = _context->createProgramFromPTXString(ptx, "mesh_intersect_refine");
else
optix_mesh.intersection = _context->createProgramFromPTXString(ptx, "mesh_intersect");
optix_mesh.bounds = _context->createProgramFromPTXString(ptx, "mesh_bounds");
//TODO !!! CHECK IF TEXTURED
loadMeshFromMRF(*mrf_mesh, optix_mesh, transform, optix_materials);
geometry_group->addChild(optix_mesh.geom_instance);
}
//if (material_handler.needMeshRefine(material_id))
// optix_mesh.intersection = _context->createProgramFromPTXString(ptx, "mesh_intersect_refine");
//else
......@@ -136,18 +158,16 @@ void OptixGeometryHandler::importMrfScene(
//DIRECTLY USE THE CORRECT ONE HERE
//apply a default lambert material to avoid optix error due to loadMesh with a geometry
//that hasn't got any material or closesthit/
optix_mesh.material = material_handler.lambert();
//optix_mesh.material = material_handler.lambert();
optix::Matrix4x4 transform = optix::Matrix4x4((*shape_it)->worldToObjectTransform().ptr());
//transform = transform.transpose();
//std::vector<optix::Material> optix_materials;
//optix_materials.push_back(material_handler.lambert());
//loadMesh(file_name, optix_mesh, transform);
loadMeshFromMRF(*mrf_mesh, optix_mesh, transform);
//optix_mesh.has_texcoords = mesh.has_texcoords;
tri_geometry_group->addChild(optix_mesh.geom_instance);
aabb.include(optix_mesh.bbox_min, optix_mesh.bbox_max);
......@@ -166,7 +186,13 @@ void OptixGeometryHandler::importMrfScene(
{
auto gi = createParallelogram(it->corner, it->v1, it->v2);
gi->addMaterial(material_handler.diffuseEmittance());
//gi->addMaterial(material_handler.diffuseEmittance());
int light_index = std::distance(optix_lights.cbegin(), it);
auto mat = light_handler.getUMatPointerQuadLight(light_index);
//gi->addMaterial(material_handler.diffuseEmittance());
gi->addMaterial(material_handler.getMaterialFromUMat(mat));
geometry_group->addChild(gi);
light_handler.addQuadLight(gi);
......@@ -178,7 +204,12 @@ void OptixGeometryHandler::importMrfScene(
{
auto gi = createSphere(it->position, it->radius);
gi->addMaterial(material_handler.diffuseEmittance());
//gi->addMaterial(material_handler.diffuseEmittance());
int light_index = std::distance(optix_sph_lights.cbegin(), it);
auto mat = light_handler.getUMatPointerSpereLight(light_index);
gi->addMaterial(material_handler.getMaterialFromUMat(mat));
geometry_group->addChild(gi);
light_handler.addSphereLight(gi);
......@@ -242,9 +273,10 @@ std::vector<std::pair<OptiXMesh, mrf::geom::Shape *>> &OptixGeometryHandler::geo
}
void OptixGeometryHandler::loadMeshFromMRF(
mrf::geom::Mesh const & mrf_mesh,
OptiXMesh & optix_mesh,
const optix::Matrix4x4 &load_xform)
mrf::geom::Mesh const & mrf_mesh,
OptiXMesh & optix_mesh,
const optix::Matrix4x4 & load_xform,
std::vector<optix::Material> optix_materials)
{
if (!optix_mesh.context)
{
......@@ -264,7 +296,7 @@ void OptixGeometryHandler::loadMeshFromMRF(
if (mrf_mesh.uvs().size() == mrf_mesh.vertices().size()) mesh.has_texcoords = true;
if (mrf_mesh.tangents().size() == mrf_mesh.vertices().size()) mesh.has_tangents = true;
mesh.num_materials = 0;
mesh.num_materials = optix_materials.size();
setupMeshLoaderInputs(context, buffers, mesh);
......@@ -302,7 +334,6 @@ void OptixGeometryHandler::loadMeshFromMRF(
//std::copy(mrf_mesh.faces().cbegin(), mrf_mesh.faces().cend(), mesh.tri_indices);
memcpy(mesh.tri_indices, &mrf_mesh.faces()[0], mrf_mesh.faces().size() * sizeof(unsigned int));
memset(mesh.mat_indices, 0, sizeof(int32_t) * mrf_mesh.faces().size() / 3);
applyLoadXForm(mesh, load_xform.getData());
......@@ -314,50 +345,87 @@ void OptixGeometryHandler::loadMeshFromMRF(
optix_mesh.bbox_max = mrf::optix_backend::make_float3(mesh.bbox_max);
optix_mesh.num_triangles = mesh.num_triangles;
std::vector<optix::Material> optix_materials;