const IfcGeom::SurfaceStyle* IfcGeom::get_style(Ifc2x3::IfcRepresentationItem* item) { std::pair<Ifc2x3::IfcSurfaceStyle*, Ifc2x3::IfcSurfaceStyleShading*> shading_styles = get_surface_style<Ifc2x3::IfcSurfaceStyleShading>(item); if (shading_styles.second == 0) { return 0; } int surface_style_id = shading_styles.first->entity->id(); std::map<int,SurfaceStyle>::const_iterator it = Cache::Style.find(surface_style_id); if (it != Cache::Style.end()) { return &(it->second); } SurfaceStyle surface_style; if (shading_styles.first->hasName()) { surface_style = SurfaceStyle(surface_style_id, shading_styles.first->Name()); } else { surface_style = SurfaceStyle(surface_style_id); } std::tr1::array<double, 3> rgb; if (process_colour(shading_styles.second->SurfaceColour(), rgb)) { surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2])); } if (shading_styles.second->is(Ifc2x3::Type::IfcSurfaceStyleRendering)) { Ifc2x3::IfcSurfaceStyleRendering* rendering_style = static_cast<Ifc2x3::IfcSurfaceStyleRendering*>(shading_styles.second); if (rendering_style->hasDiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) { SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().get_value_or(SurfaceStyle::ColorComponent(1,1,1)); surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(diffuse.R() * rgb[0], diffuse.G() * rgb[1], diffuse.B() * rgb[2])); } if (rendering_style->hasDiffuseTransmissionColour()) { // Not supported } if (rendering_style->hasReflectionColour()) { // Not supported } if (rendering_style->hasSpecularColour() && process_colour(rendering_style->SpecularColour(), rgb)) { surface_style.Specular().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2])); } if (rendering_style->hasSpecularHighlight()) { IfcUtil::IfcArgumentSelect* highlight = static_cast<IfcUtil::IfcArgumentSelect*>(rendering_style->SpecularHighlight()); if (highlight->is(Ifc2x3::Type::IfcSpecularRoughness)) { double roughness = *highlight->wrappedValue(); if (roughness >= 1e-9) { surface_style.Specularity().reset(1.0 / roughness); } } else if (highlight->is(Ifc2x3::Type::IfcSpecularExponent)) { surface_style.Specularity().reset(*highlight->wrappedValue()); } } if (rendering_style->hasTransmissionColour()) { // Not supported } if (rendering_style->hasTransparency()) { const double d = rendering_style->Transparency(); surface_style.Transparency().reset(d); } } return &(Cache::Style[surface_style_id] = surface_style); }
const IfcGeom::SurfaceStyle* IfcGeom::Kernel::internalize_surface_style(const std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*>& shading_styles) { if (shading_styles.second == 0) { return 0; } int surface_style_id = shading_styles.first->entity->id(); std::map<int,SurfaceStyle>::const_iterator it = style_cache.find(surface_style_id); if (it != style_cache.end()) { return &(it->second); } SurfaceStyle surface_style; if (shading_styles.first->hasName()) { surface_style = SurfaceStyle(surface_style_id, shading_styles.first->Name()); } else { surface_style = SurfaceStyle(surface_style_id); } double rgb[3]; if (process_colour(shading_styles.second->SurfaceColour(), rgb)) { surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2])); } if (shading_styles.second->is(IfcSchema::Type::IfcSurfaceStyleRendering)) { IfcSchema::IfcSurfaceStyleRendering* rendering_style = static_cast<IfcSchema::IfcSurfaceStyleRendering*>(shading_styles.second); if (rendering_style->hasDiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) { SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().get_value_or(SurfaceStyle::ColorComponent(1,1,1)); surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(diffuse.R() * rgb[0], diffuse.G() * rgb[1], diffuse.B() * rgb[2])); } if (rendering_style->hasDiffuseTransmissionColour()) { // Not supported } if (rendering_style->hasReflectionColour()) { // Not supported } if (rendering_style->hasSpecularColour() && process_colour(rendering_style->SpecularColour(), rgb)) { surface_style.Specular().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2])); } if (rendering_style->hasSpecularHighlight()) { IfcSchema::IfcSpecularHighlightSelect* highlight = rendering_style->SpecularHighlight(); if (highlight->is(IfcSchema::Type::IfcSpecularRoughness)) { double roughness = *((IfcSchema::IfcSpecularRoughness*)highlight); if (roughness >= 1e-9) { surface_style.Specularity().reset(1.0 / roughness); } } else if (highlight->is(IfcSchema::Type::IfcSpecularExponent)) { surface_style.Specularity().reset(*((IfcSchema::IfcSpecularExponent*)highlight)); } } if (rendering_style->hasTransmissionColour()) { // Not supported } if (rendering_style->hasTransparency()) { const double d = rendering_style->Transparency(); surface_style.Transparency().reset(d); } } return &(style_cache[surface_style_id] = surface_style); }