Skip to content

Commit

Permalink
Implement support for custom default materials
Browse files Browse the repository at this point in the history
The support for custom default materials is implemented as a JSON
file passed via the command line. The default material specification
will override the defaults, except the toplevel default value.
  • Loading branch information
hypirion authored and aothms committed Oct 15, 2018
1 parent 882d27f commit dab3382
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
14 changes: 12 additions & 2 deletions src/ifcconvert/IfcConvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "../ifcconvert/SvgSerializer.h"

#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcgeom/IfcGeomRenderStyles.h"

#include <IGESControl_Controller.hxx>
#include <Standard_Version.hxx>
Expand Down Expand Up @@ -178,7 +179,8 @@ int main(int argc, char** argv)
inclusion_traverse_filter include_traverse_filter;
exclusion_filter exclude_filter;
exclusion_traverse_filter exclude_traverse_filter;
std::string filter_filename;
std::string filter_filename;
std::string default_material_filename;

po::options_description geom_options("Geometry options");
geom_options.add_options()
Expand Down Expand Up @@ -259,7 +261,11 @@ int main(int argc, char** argv)
"Specifies a filter file that describes the used filtering criteria. Supported formats "
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimiters."
"Multiple filters of same type with different values can be inserted on their own lines. "
"See --include, --include+, --exclude, and --exclude+ for more details.");
"See --include, --include+, --exclude, and --exclude+ for more details.")
("default-material-file", po::value<std::string>(&default_material_filename),
"Specifies a material file that describes the material object types will have"
"if an object does not have any specified material in the IFC file.");


std::string bounds, offset_str;
#ifdef HAVE_ICU
Expand Down Expand Up @@ -491,6 +497,10 @@ int main(int argc, char** argv)
}
}

if (!default_material_filename.empty()) {
IfcGeom::set_default_style(default_material_filename);
}

/// @todo Clean up this filter code further.
std::vector<geom_filter> used_filters;
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }
Expand Down
49 changes: 49 additions & 0 deletions src/ifcgeom/IfcGeomRenderStyles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@
* *
********************************************************************************/

#include <boost/optional/optional.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

#include <map>

#include "IfcGeom.h"

namespace pt = boost::property_tree;

bool process_colour(IfcSchema::IfcColourRgb* colour, double* rgb) {
if (colour != 0) {
rgb[0] = colour->Red();
Expand Down Expand Up @@ -170,6 +176,49 @@ void InitDefaultMaterials() {
default_materials_initialized = true;
}

void IfcGeom::set_default_style(const std::string& json_file) {
if (default_materials_initialized) {
default_materials.clear();
}

pt::ptree root;
pt::read_json(json_file, root);

for (pt::ptree::value_type &material_pair : root) {
std::string name = material_pair.first;
default_materials.insert(std::make_pair(name, IfcGeom::SurfaceStyle(name)));

pt::ptree material = material_pair.second;
boost::optional<pt::ptree&> diffuse = material.get_child_optional("diffuse");
if (diffuse) {
double rgb[3];
int i = 0;
for (pt::ptree::value_type &colour : diffuse.get()) {
rgb[i] = colour.second.get_value<double>();
i++;
}
default_materials[name].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
boost::optional<pt::ptree&> specular = material.get_child_optional("specular");
if (specular) {
double rgb[3];
int i = 0;
for (pt::ptree::value_type &colour : specular.get()) {
rgb[i] = colour.second.get_value<double>();
i++;
}
default_materials[name].Specular().reset(IfcGeom::SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
boost::optional<double> specular_roughness = material.get_optional<double>("specular-roughness");
if (specular_roughness) {
default_materials[name].Specularity().reset(1.0 / specular_roughness.get());
}
default_materials[name].Transparency() = material.get_optional<double>("transparency");
}

default_materials_initialized = true;
}

const IfcGeom::SurfaceStyle* IfcGeom::get_default_style(const std::string& s) {
if (!default_materials_initialized) InitDefaultMaterials();
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find(s);
Expand Down
3 changes: 2 additions & 1 deletion src/ifcgeom/IfcGeomRenderStyles.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ namespace IfcGeom {
boost::optional<double>& Specularity() { return specularity; }
};

IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
IFC_GEOM_API void set_default_style(const std::string& json_file);
}

#endif

0 comments on commit dab3382

Please sign in to comment.