Skip to content

Commit dab3382

Browse files
hypirionaothms
authored andcommitted
Implement support for custom default materials
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.
1 parent 882d27f commit dab3382

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/ifcconvert/IfcConvert.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "../ifcconvert/SvgSerializer.h"
3535

3636
#include "../ifcgeom/IfcGeomIterator.h"
37+
#include "../ifcgeom/IfcGeomRenderStyles.h"
3738

3839
#include <IGESControl_Controller.hxx>
3940
#include <Standard_Version.hxx>
@@ -178,7 +179,8 @@ int main(int argc, char** argv)
178179
inclusion_traverse_filter include_traverse_filter;
179180
exclusion_filter exclude_filter;
180181
exclusion_traverse_filter exclude_traverse_filter;
181-
std::string filter_filename;
182+
std::string filter_filename;
183+
std::string default_material_filename;
182184

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

264270
std::string bounds, offset_str;
265271
#ifdef HAVE_ICU
@@ -491,6 +497,10 @@ int main(int argc, char** argv)
491497
}
492498
}
493499

500+
if (!default_material_filename.empty()) {
501+
IfcGeom::set_default_style(default_material_filename);
502+
}
503+
494504
/// @todo Clean up this filter code further.
495505
std::vector<geom_filter> used_filters;
496506
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }

src/ifcgeom/IfcGeomRenderStyles.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@
1717
* *
1818
********************************************************************************/
1919

20+
#include <boost/optional/optional.hpp>
21+
#include <boost/property_tree/json_parser.hpp>
22+
#include <boost/property_tree/ptree.hpp>
23+
2024
#include <map>
2125

2226
#include "IfcGeom.h"
2327

28+
namespace pt = boost::property_tree;
29+
2430
bool process_colour(IfcSchema::IfcColourRgb* colour, double* rgb) {
2531
if (colour != 0) {
2632
rgb[0] = colour->Red();
@@ -170,6 +176,49 @@ void InitDefaultMaterials() {
170176
default_materials_initialized = true;
171177
}
172178

179+
void IfcGeom::set_default_style(const std::string& json_file) {
180+
if (default_materials_initialized) {
181+
default_materials.clear();
182+
}
183+
184+
pt::ptree root;
185+
pt::read_json(json_file, root);
186+
187+
for (pt::ptree::value_type &material_pair : root) {
188+
std::string name = material_pair.first;
189+
default_materials.insert(std::make_pair(name, IfcGeom::SurfaceStyle(name)));
190+
191+
pt::ptree material = material_pair.second;
192+
boost::optional<pt::ptree&> diffuse = material.get_child_optional("diffuse");
193+
if (diffuse) {
194+
double rgb[3];
195+
int i = 0;
196+
for (pt::ptree::value_type &colour : diffuse.get()) {
197+
rgb[i] = colour.second.get_value<double>();
198+
i++;
199+
}
200+
default_materials[name].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
201+
}
202+
boost::optional<pt::ptree&> specular = material.get_child_optional("specular");
203+
if (specular) {
204+
double rgb[3];
205+
int i = 0;
206+
for (pt::ptree::value_type &colour : specular.get()) {
207+
rgb[i] = colour.second.get_value<double>();
208+
i++;
209+
}
210+
default_materials[name].Specular().reset(IfcGeom::SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
211+
}
212+
boost::optional<double> specular_roughness = material.get_optional<double>("specular-roughness");
213+
if (specular_roughness) {
214+
default_materials[name].Specularity().reset(1.0 / specular_roughness.get());
215+
}
216+
default_materials[name].Transparency() = material.get_optional<double>("transparency");
217+
}
218+
219+
default_materials_initialized = true;
220+
}
221+
173222
const IfcGeom::SurfaceStyle* IfcGeom::get_default_style(const std::string& s) {
174223
if (!default_materials_initialized) InitDefaultMaterials();
175224
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find(s);

src/ifcgeom/IfcGeomRenderStyles.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ namespace IfcGeom {
9696
boost::optional<double>& Specularity() { return specularity; }
9797
};
9898

99-
IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
99+
IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
100+
IFC_GEOM_API void set_default_style(const std::string& json_file);
100101
}
101102

102103
#endif

0 commit comments

Comments
 (0)