diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index a3bbf5739b..5a622daa98 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -351,6 +351,13 @@ namespace ifcopenshell { static constexpr bool defaultvalue = false; }; + struct SurfaceColour : public SettingBase { + static constexpr const char* const name = "surface-colour"; + static constexpr const char* const description = + "Prioritizes the surface color instead of using diffuse."; + static constexpr bool defaultvalue = false; + }; + enum PiecewiseStepMethod { MAXSTEPSIZE, MINSTEPS }; @@ -486,7 +493,7 @@ namespace ifcopenshell { }; class IFC_GEOM_API Settings : public SettingsContainer< - std::tuple + std::tuple > {}; } diff --git a/src/ifcgeom/IfcGeomRepresentation.cpp b/src/ifcgeom/IfcGeomRepresentation.cpp index 1da38a69de..c888efba2a 100644 --- a/src/ifcgeom/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/IfcGeomRepresentation.cpp @@ -148,7 +148,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep) int sid = -1; if (it->hasStyle()) { - const auto& clr = it->Style().diffuse.ccomponents(); + const auto& clr = it->Style().get_color().ccomponents(); surface_styles_.push_back(clr(0)); surface_styles_.push_back(clr(1)); surface_styles_.push_back(clr(2)); diff --git a/src/ifcgeom/SurfaceStyle.cpp b/src/ifcgeom/SurfaceStyle.cpp index 3d862b4825..69310f3929 100644 --- a/src/ifcgeom/SurfaceStyle.cpp +++ b/src/ifcgeom/SurfaceStyle.cpp @@ -89,6 +89,10 @@ void IfcGeom::set_default_style_file(const std::string& json_file) { boost::optional diffuse = material.get_child_optional("diffuse"); default_materials[name]->diffuse = read_colour_component(diffuse); + // @todo Is it necessary to get the surface too? + // boost::optional surface = material.get_child_optional("surface"); + // default_materials[name]->surface = read_colour_component(surface); + boost::optional specular = material.get_child_optional("specular"); default_materials[name]->specular = read_colour_component(specular); diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp index 202d85e2f4..7c0235cfa3 100644 --- a/src/ifcgeom/mapping/mapping.cpp +++ b/src/ifcgeom/mapping/mapping.cpp @@ -565,11 +565,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { return surface_style; } - static taxonomy::colour white = taxonomy::colour(1., 1., 1.); - double rgb[3]; - if (process_colour(shading->SurfaceColour(), rgb)) { - surface_style->diffuse.components() << rgb[0], rgb[1], rgb[2]; - } + surface_style->use_surface_color = settings_.get().get(); + + static taxonomy::colour white = taxonomy::colour(1., 1., 1.); + double rgb[3]; + if (process_colour(shading->SurfaceColour(), rgb)) { + surface_style->surface.components() << rgb[0], rgb[1], rgb[2]; + surface_style->diffuse = surface_style->surface; + } if (auto rendering_style = shading->as()) { if (rendering_style->DiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) { diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 13164daebf..2c119c9e4c 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -305,8 +305,10 @@ typedef item const* ptr; std::string name; colour diffuse; + colour surface; colour specular; double specularity, transparency; + bool use_surface_color; void print(std::ostream& o, int indent = 0) const; @@ -314,15 +316,22 @@ typedef item const* ptr; virtual kinds kind() const { return STYLE; } virtual size_t calc_hash() const { - auto v = std::make_tuple(static_cast(STYLE), name, diffuse.hash(), specular.hash(), specularity, transparency); + auto v = std::make_tuple(static_cast(STYLE), name, diffuse.hash(), surface.hash(), specular.hash(), specularity, transparency); return boost::hash{}(v); } // @todo equality implementation based on values? bool operator==(const style& other) const { return instance == other.instance; } - style() : specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()) {} - style(const std::string& name) : name(name), specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()) {} + style() : specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()), use_surface_color(false) {} + style(const std::string& name) : name(name), specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()), use_surface_color(false) {} + + const colour& get_color() const { + if (use_surface_color && surface) { + return surface; + } + return diffuse; + } bool has_specularity() const { return !std::isnan(specularity); diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index 15cd7e546b..fdb349a0fb 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -354,8 +354,8 @@ protected: std::vector > > diffuse_color_array; for (auto it = geom->geometry().materials().begin(); it != geom->geometry().materials().end(); ++it) { const auto& mat = **it; - if (mat.diffuse) { - const auto& color = mat.diffuse.ccomponents(); + if (mat.get_color()) { + const auto& color = mat.get_color().ccomponents(); diffuse_color_array.push_back(std::array{ static_cast(color(0)), static_cast(color(1)), diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp index 4dbfd003e1..84da31dc86 100644 --- a/src/serializers/GltfSerializer.cpp +++ b/src/serializers/GltfSerializer.cpp @@ -97,9 +97,9 @@ int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style: std::array base; base.fill(1.0); - if (style->diffuse) { + if (style->get_color()) { for (int i = 0; i < 3; ++i) { - base[i] = style->diffuse.ccomponents()(i); + base[i] = style->get_color().ccomponents()(i); } } if (style->transparency == style->transparency) { diff --git a/src/serializers/WavefrontObjSerializer.cpp b/src/serializers/WavefrontObjSerializer.cpp index 0414659b98..300fceeb88 100644 --- a/src/serializers/WavefrontObjSerializer.cpp +++ b/src/serializers/WavefrontObjSerializer.cpp @@ -67,7 +67,7 @@ void WaveFrontOBJSerializer::writeMaterial(const ifcopenshell::geometry::taxonom mtl_stream.stream << "newmtl " << material_name << "\n"; { - auto& diffuse = style.diffuse.ccomponents(); + auto& diffuse = style.get_color().ccomponents(); mtl_stream.stream << "Kd " << diffuse(0) << " " << diffuse(1) << " " << diffuse(2) << "\n"; } if (style.specular) {