Commit abdfb1b1 authored by DUFAY Arthur's avatar DUFAY Arthur

Add ext path resources feature

parent 9257a728
......@@ -64,6 +64,9 @@
</li>
</ul>
</li>
<li class="current toctree_l2">
<a class="current" href="./scene_format.md.html#toc5">Paths to external resources</a>
</li>
</ul>
</li>
<li class="toctree_l1">
......@@ -262,6 +265,34 @@ Here is an example of how to specify both spectral and rgb envmap in a scene.
<background type="envmap" ref_envmap="my_envmap" ref_envmap_spectral="my_envmap_spectral" /></background>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Paths to external resources
While using an external resources such as an <a class="current" href="./scene_format.md.html#toc4.3">environment map</a>, or loading a file for a <a class="current" href="./scene_format.md.html#toc3.2">Measured Isotropic BRDF</a>, you may need to add some resources path.
This can be done using the XML tag `<resources_path>` inside `<ext_resources>`.
To retrieve a file mrf applies the following rules:
- Paths are always relative to the scene file (.msf) folder which is considered as <font color="green">the current directory</font>.
- (First try) First mrf will try to load your file in the <font color="green">current directory</font> and adding at the end of the path, <font color="#7092BE">the relative path</font> specify in your xml attribute file="..."
- (Second try) If not found tries from <font color="green">currrent_directory</font> + <font color="purple">a_resource_path</font> + <font color="#7092BE">relative_path_to_your_file</font>
- (Third try) If not found tries from <font color="green">currrent_directory</font> + <font color="purple">a_resource_path</font> + <font color="#99D9EA">name_of_your_file</font>
The <font color="#99D9EA">name_of_your_file</font> is deduced from the <font color="#7092BE">relative_path_to_your_file</font> by removing all the previous directory in it.
For instance the following code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML
<!-- /c/mrf/scenes/myscene.msf -->
<ext_resources>
<resources_path path="./materials" />
<resources_path path="../envmaps" />
<envmaps>
<panoramic file="./env/green_point_park_4k.hdr" name="my_envmap" />
</envmaps>
</ext_resources>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
in the file <font color="green">/c/mrf/scenes/</font>myscene.msf will try to look for the file green_point_park_4k.hdr in:
- (First try) <font color="green">/c/mrf/scenes/</font><font color="#7092BE">env/green_point_park_4k.hdr</font>
- (Second try) <font color="green">/c/mrf/scenes/</font><font color="purple">materials/</font><font color="#7092BE">env/green_point_park_4k.hdr</font>
- (Second try) <font color="green">/c/mrf/scenes/</font><font color="purple">../envmaps/</font><font color="#7092BE">env/green_point_park_4k.hdr</font> (equivalent to <font color="green">/c/mrf/</font><font color="purple">envmaps/</font><font color="#7092BE">env/green_point_park_4k.hdr</font>)
- (Third try) <font color="green">/c/mrf/scenes/</font><font color="purple">materials/</font><font color="#99D9EA">green_point_park_4k.hdr</font>
- (Third try) <font color="green">/c/mrf/scenes/</font><font color="purple">../envmaps/</font><font color="#99D9EA">green_point_park_4k.hdr</font> (equivalent to <font color="green">/c/mrf/</font><font color="purple">envmaps/</font><font color="#99D9EA">green_point_park_4k.hdr</font>)
## Quad Light
......
......@@ -19,6 +19,10 @@
#include <fstream>
#include <algorithm>
#include <string>
#include <vector>
#include "gui/feedback/loger.hpp"
#include "util/string_parsing.hpp"
//disable warning for fopen and fscanf on visual studio
#ifdef _MSC_VER
......@@ -29,6 +33,85 @@ namespace mrf
{
namespace io
{
/**
* Returns true if file exists
**/
inline bool file_exists( std::string const & filename) {
std::ifstream ifile(filename.c_str());
return (bool)ifile;
}
/**
* try to find a file by concataning current_directory and relative_file_path
* If not found try each folder in folders (concataning folder and relative_file_path)
* If not found try each folder in folders (concataning folder and file_path extracted from relative_file_path)
*
* Store result in found_path (first one found)
* Return true if a file is found
**/
inline bool find_file_from_folders(mrf::gui::fb::Loger const & loger,
std::string const & current_directory,
std::vector<std::string> const & directories,
std::string const & relative_file_path,
std::string & found_path) {
std::string filename;
mrf::util::StringParsing::fileNameFromAbsPath(relative_file_path.c_str(), filename);
bool file_found = false;
//Try from current folder
std::string path = current_directory + relative_file_path;
if (mrf::io::file_exists(path))
{
file_found = true;
loger.trace("FOUND AT: ", path);
}
//try from one of ext resources paths
if (!file_found)
{
for (const auto & folder : directories)
{
path = current_directory + folder + relative_file_path;
loger.trace(" Try: ", path);
if (mrf::io::file_exists(path))
{
file_found = true;
loger.trace("FOUND AT: ", path);
break;
}
}
}
//try from one of ext resources paths,
//without the relative path from the xml attrib
if (!file_found)
{
for (const auto & folder : directories)
{
path = current_directory + folder + filename;
loger.trace(" Try: ", path);
if (mrf::io::file_exists(path))
{
file_found = true;
loger.trace("FOUND AT: ", path);
break;
}
}
}
if (!file_found)
{
loger.warn("File does not exists in any externals paths, Path of file is: ", relative_file_path);
return false;
}
found_path = path;
return true;
}
class MRF_EXPORT _FileIO
{
......
......@@ -246,6 +246,8 @@ class MRF_EXPORT SceneLexer : public Lexer
//EXTERNAL RESOURCES
static constexpr char const * const EXT_RESOURCES_MK = "ext_resources";
static constexpr char const * const RESOURCES_PATH_MK = "resources_path";
static constexpr char const * const PATH_AT = "path";
static constexpr char const * const ENV_LIGHTS_MK = "env_lights";
static constexpr char const * const ENVMAPS_MK = "envmaps";
static constexpr char const * const PANORAMIC_ENVMAP_MK = "panoramic";
......
......@@ -139,6 +139,13 @@ SceneParser::parsingScene( Scene & scene )
// OBJ File (as scene)
// PLY File (as scene)
//-------------------------------------------------------------------------
bool correctly_parsed_resources_path = true;
if (!parseResourcesPath(scene))
{
_loger->warn(" Problem with resources path ");
correctly_parsed_resources_path = false;
}
bool correctly_parsed_extresources = true;
if( !parseExternalResources( scene ) )
{
......@@ -184,8 +191,11 @@ SceneParser::parsingScene( Scene & scene )
return correctly_parsed_extresources &&
//we do not return the error due to bad parsing
//of ext resources to allow the user to still render an
//image even though some envmaps or other ext resources
//can't be loaded
return //correctly_parsed_extresources &&
correctly_parsed_shapes &&
correctly_parsed_lights &&
correctly_parsed_global_material &&
......@@ -1466,21 +1476,20 @@ SceneParser::addMaterial( XMLElement* a_mat_element, mrf::rendering::Scene & sce
return false;
}
std::string brdf_filename;
mrf::util::StringParsing::fileNameFromAbsPath(brdf_relative_path.c_str(), brdf_filename);
std::string brdf_folder_path;
mrf::util::StringParsing::getDirectory(brdf_relative_path.c_str(), brdf_folder_path);
brdf_folder_path = _current_directory + brdf_folder_path;
string brdf_absolut_path = brdf_folder_path + brdf_filename;
_loger->trace(" Load Alta file: ", brdf_absolut_path);
std::string path;
mrf::AltaHEADER alta_header;
float * data = nullptr;
mrf::AltaReader::readData<float>(brdf_absolut_path, alta_header, data, _loger);
if (mrf::io::find_file_from_folders(*_loger,
_current_directory,
_ext_paths,
brdf_relative_path,
path))
{
mrf::AltaReader::readData<float>(path, alta_header, data, _loger);
}
struct wrong_data_func
{
bool operator()(const string& value)
......@@ -2883,6 +2892,46 @@ SceneParser::retrieveDirection( XMLElement* elem, mrf::math::Vec3f & direction )
}
bool SceneParser::parseResourcesPath(Scene & scene)
{
_loger->trace("Looking for Resources Path ");
bool status_return = true;
//Parse envmaps
XMLElement* ext = _doc_handle.FirstChildElement(SceneLexer::SCENE_MK).FirstChildElement(SceneLexer::EXT_RESOURCES_MK).ToElement();
if (ext && ext->FirstChildElement(SceneLexer::RESOURCES_PATH_MK))
{
//Looking for Panoramic Envmap
XMLElement* elem = ext->FirstChildElement(SceneLexer::RESOURCES_PATH_MK)->ToElement();
if (elem)
{
for (; elem;
elem = elem->NextSiblingElement(SceneLexer::RESOURCES_PATH_MK) )
{
if (elem->Attribute(SceneLexer::PATH_AT))
{
string temp_path = elem->Attribute(SceneLexer::PATH_AT);
if (temp_path.size()>1 && temp_path[temp_path.size() - 1] != '/')
{
temp_path = temp_path + "/";
}
_ext_paths.push_back(temp_path);
_loger->trace(" Found Ext path: ",temp_path);
}
else
{
status_return = false;
}
}
}
}
return status_return;
}
bool SceneParser::parseExternalResources( Scene & scene )
{
......@@ -2940,7 +2989,16 @@ bool SceneParser::parseEnvmapGenericAttributes(XMLElement* elem, string & name,
_loger->trace(" Found : ENVMAP FILE: ");
_loger->trace(env_file);
path = _current_directory + env_file;
if ( ! mrf::io::find_file_from_folders(*_loger,
_current_directory,
_ext_paths,
env_file,
path))
{
return false;
}
_loger->trace(" Full Path of file is: ", path);
theta = 0.0f;
......
......@@ -78,6 +78,11 @@ class MRF_EXPORT SceneParser
**/
std::map< std::string, mrf::lighting::EnvMap* > _envmap_map;
/**
* For external paths
**/
std::vector<std::string> _ext_paths;
private:
void cleanString( std::string & str );
bool parsingScene( mrf::rendering::Scene & scene );
......@@ -167,7 +172,7 @@ class MRF_EXPORT SceneParser
inline bool retrieveMaterialIndex( tinyxml2::XMLElement* elem, unsigned int & material_index) const;
bool parseResourcesPath(mrf::rendering::Scene & scene);
//-------------------------------------------------------------------------
// External Resources
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment