Files
IfcOpenShell/src/ifcgeom/IfcGeomRenderStyles.cpp
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

141 lines
6.4 KiB
C++
Raw Normal View History

2013-05-13 06:40:30 +00:00
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#include <map>
#include "IfcGeom.h"
2013-05-13 06:40:30 +00:00
2017-12-20 16:38:55 +01:00
namespace {
bool process_colour(IfcSchema::IfcColourRgb* colour, double* rgb) {
if (colour != 0) {
rgb[0] = colour->Red();
rgb[1] = colour->Green();
rgb[2] = colour->Blue();
}
return colour != 0;
2013-05-13 06:40:30 +00:00
}
2017-12-20 16:38:55 +01:00
bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, double* rgb) {
if (factor != 0) {
const double f = *factor;
rgb[0] = rgb[1] = rgb[2] = f;
}
return factor != 0;
2013-05-13 06:40:30 +00:00
}
2017-12-20 16:38:55 +01:00
bool process_colour(IfcSchema::IfcColourOrFactor* colour_or_factor, double* rgb) {
if (colour_or_factor == 0) {
return false;
} else if (colour_or_factor->declaration().is(IfcSchema::IfcColourRgb::Class())) {
return process_colour(static_cast<IfcSchema::IfcColourRgb*>(colour_or_factor), rgb);
} else if (colour_or_factor->declaration().is(IfcSchema::IfcNormalisedRatioMeasure::Class())) {
return process_colour(static_cast<IfcSchema::IfcNormalisedRatioMeasure*>(colour_or_factor), rgb);
} else {
return false;
}
2013-05-13 06:40:30 +00:00
}
2017-12-20 16:38:55 +01:00
2013-05-13 06:40:30 +00:00
}
2017-12-20 16:38:55 +01:00
#define Kernel MAKE_TYPE_NAME(Kernel)
const IfcGeom::SurfaceStyle* IfcGeom::Kernel::internalize_surface_style(const std::pair<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*>& shading_styles) {
2013-05-13 06:40:30 +00:00
if (shading_styles.second == 0) {
return 0;
}
2017-12-11 15:07:40 +01:00
int surface_style_id = shading_styles.first->data().id();
std::map<int,SurfaceStyle>::const_iterator it = style_cache.find(surface_style_id);
if (it != style_cache.end()) {
2013-05-13 06:40:30 +00:00
return &(it->second);
}
SurfaceStyle surface_style;
IfcSchema::IfcSurfaceStyle* style = shading_styles.first->as<IfcSchema::IfcSurfaceStyle>();
IfcSchema::IfcSurfaceStyleShading* shading = shading_styles.second->as<IfcSchema::IfcSurfaceStyleShading>();
2021-07-29 14:54:51 +02:00
if (style->Name()) {
surface_style = SurfaceStyle(surface_style_id, *style->Name());
2013-05-13 06:40:30 +00:00
} else {
surface_style = SurfaceStyle(surface_style_id);
}
double rgb[3];
if (process_colour(shading->SurfaceColour(), rgb)) {
2013-05-13 06:40:30 +00:00
surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
2017-12-18 15:25:09 +01:00
if (shading_styles.second->declaration().is(IfcSchema::IfcSurfaceStyleRendering::Class())) {
IfcSchema::IfcSurfaceStyleRendering* rendering_style = static_cast<IfcSchema::IfcSurfaceStyleRendering*>(shading_styles.second);
2021-07-29 14:54:51 +02:00
if (rendering_style->DiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) {
2013-05-13 06:40:30 +00:00
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]));
}
2021-07-29 14:54:51 +02:00
if (rendering_style->DiffuseTransmissionColour()) {
2013-05-13 06:40:30 +00:00
// Not supported
}
2021-07-29 14:54:51 +02:00
if (rendering_style->ReflectionColour()) {
2013-05-13 06:40:30 +00:00
// Not supported
}
2021-07-29 14:54:51 +02:00
if (rendering_style->SpecularColour() && process_colour(rendering_style->SpecularColour(), rgb)) {
2013-05-13 06:40:30 +00:00
surface_style.Specular().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
2021-07-29 14:54:51 +02:00
if (rendering_style->SpecularHighlight()) {
IfcSchema::IfcSpecularHighlightSelect* highlight = rendering_style->SpecularHighlight();
2017-12-18 15:25:09 +01:00
if (highlight->declaration().is(IfcSchema::IfcSpecularRoughness::Class())) {
double roughness = *((IfcSchema::IfcSpecularRoughness*)highlight);
2013-05-13 06:40:30 +00:00
if (roughness >= 1e-9) {
surface_style.Specularity().reset(1.0 / roughness);
}
2017-12-18 15:25:09 +01:00
} else if (highlight->declaration().is(IfcSchema::IfcSpecularExponent::Class())) {
surface_style.Specularity().reset(*((IfcSchema::IfcSpecularExponent*)highlight));
2013-05-13 06:40:30 +00:00
}
}
2021-07-29 14:54:51 +02:00
if (rendering_style->TransmissionColour()) {
2013-05-13 06:40:30 +00:00
// Not supported
}
2021-07-29 14:54:51 +02:00
if (rendering_style->Transparency()) {
const double d = *rendering_style->Transparency();
2013-05-13 06:40:30 +00:00
surface_style.Transparency().reset(d);
}
}
return &(style_cache[surface_style_id] = surface_style);
2013-05-13 06:40:30 +00:00
}
2015-10-07 17:33:30 +02:00
const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationItem* item) {
return internalize_surface_style(get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item));
}
const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcMaterial* material) {
IfcSchema::IfcMaterialDefinitionRepresentation::list::ptr defs = material->HasRepresentation();
2016-04-09 17:54:23 +02:00
for (IfcSchema::IfcMaterialDefinitionRepresentation::list::it jt = defs->begin(); jt != defs->end(); ++jt) {
2015-10-07 17:33:30 +02:00
IfcSchema::IfcRepresentation::list::ptr reps = (*jt)->Representations();
IfcSchema::IfcStyledItem::list::ptr styles(new IfcSchema::IfcStyledItem::list);
2016-04-09 17:54:23 +02:00
for (IfcSchema::IfcRepresentation::list::it it = reps->begin(); it != reps->end(); ++it) {
2015-10-07 17:33:30 +02:00
styles->push((**it).Items()->as<IfcSchema::IfcStyledItem>());
}
2016-04-09 17:54:23 +02:00
for (IfcSchema::IfcStyledItem::list::it it = styles->begin(); it != styles->end(); ++it) {
const std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*> ss = get_surface_style<IfcSchema::IfcSurfaceStyleShading>(*it);
2015-10-07 17:33:30 +02:00
if (ss.second) {
return internalize_surface_style(ss);
}
}
}
2018-12-12 16:29:10 +01:00
IfcGeom::SurfaceStyle material_style = IfcGeom::SurfaceStyle(material->data().id(), material->Name());
return &(style_cache[material->data().id()] = material_style);
2015-10-07 17:33:30 +02:00
}