Added missing files

This commit is contained in:
Thomas Krijnen
2013-05-13 06:40:30 +00:00
parent 259cfa895e
commit 1d1fd49608
3 changed files with 327 additions and 3 deletions
+170
View File
@@ -0,0 +1,170 @@
/********************************************************************************
* *
* 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 <array>
#include "IfcGeomRenderStyles.h"
namespace IfcGeom {
namespace Cache {
std::map<int,SurfaceStyle> Style;
void PurgeStyleCache() {
Style.clear();
}
}
}
bool process_colour(Ifc2x3::IfcColourRgb* colour, std::array<double, 3>& rgb) {
if (colour != 0) {
rgb[0] = colour->Red();
rgb[1] = colour->Green();
rgb[2] = colour->Blue();
}
return colour != 0;
}
bool process_colour(IfcUtil::IfcArgumentSelect* factor, std::array<double, 3>& rgb) {
if (factor != 0) {
const double f = *factor->wrappedValue();
rgb[0] = rgb[1] = rgb[2] = f;
}
return factor != 0;
}
bool process_colour(Ifc2x3::IfcColourOrFactor colour_or_factor, std::array<double, 3>& rgb) {
if (colour_or_factor == 0) {
return false;
} else if (colour_or_factor->is(Ifc2x3::Type::IfcColourRgb)) {
return process_colour(static_cast<Ifc2x3::IfcColourRgb*>(colour_or_factor), rgb);
} else if (colour_or_factor->is(Ifc2x3::Type::IfcNormalisedRatioMeasure)) {
return process_colour(static_cast<IfcUtil::IfcArgumentSelect*>(colour_or_factor), rgb);
} else {
return false;
}
}
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::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::IfcSpecularRoughness)) {
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);
}
static std::map<std::string, IfcGeom::SurfaceStyle> default_materials;
static IfcGeom::SurfaceStyle default_material;
static bool default_materials_initialized = false;
void InitDefaultMaterials() {
default_materials.insert(std::make_pair("IfcSite", IfcGeom::SurfaceStyle("IfcSite")));
default_materials["IfcSite" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.75, 0.8, 0.65));
default_materials.insert(std::make_pair("IfcSlab", IfcGeom::SurfaceStyle("IfcSlab")));
default_materials["IfcSlab" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.4 , 0.4, 0.4 ));
default_materials.insert(std::make_pair("IfcWallStandardCase", IfcGeom::SurfaceStyle("IfcWallStandardCase")));
default_materials["IfcWallStandardCase"].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.9 , 0.9, 0.9 ));
default_materials.insert(std::make_pair("IfcWall", IfcGeom::SurfaceStyle("IfcWall")));
default_materials["IfcWall" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.9 , 0.9, 0.9 ));
default_materials.insert(std::make_pair("IfcWindow", IfcGeom::SurfaceStyle("IfcWindow")));
default_materials["IfcWindow" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.75, 0.8, 0.75));
default_materials["IfcWindow" ].Transparency().reset(0.3);
default_materials.insert(std::make_pair("IfcDoor", IfcGeom::SurfaceStyle("IfcDoor")));
default_materials["IfcDoor" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.55, 0.3, 0.15));
default_materials.insert(std::make_pair("IfcBeam", IfcGeom::SurfaceStyle("IfcBeam")));
default_materials["IfcBeam" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.75, 0.7, 0.7 ));
default_materials.insert(std::make_pair("IfcRailing", IfcGeom::SurfaceStyle("IfcRailing")));
default_materials["IfcRailing" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.65, 0.6, 0.6 ));
default_materials.insert(std::make_pair("IfcMember", IfcGeom::SurfaceStyle("IfcMember")));
default_materials["IfcMember" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.65, 0.6, 0.6 ));
default_materials.insert(std::make_pair("IfcPlate", IfcGeom::SurfaceStyle("IfcPlate")));
default_materials["IfcPlate" ].Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.8 , 0.8, 0.8 ));
default_material = IfcGeom::SurfaceStyle("DefaultMaterial");
default_material.Diffuse().reset(IfcGeom::SurfaceStyle::ColorComponent(0.7, 0.7, 0.7));
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);
if (it == default_materials.end()) return &default_material;
else {
const IfcGeom::SurfaceStyle& surface_style = it->second;
return &surface_style;
}
}
+134
View File
@@ -0,0 +1,134 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
#ifndef IFCGEOMRENDERSTYLES_H
#define IFCGEOMRENDERSTYLES_H
#include <array>
#include "../ifcparse/Ifc2x3.h"
namespace IfcGeom {
class SurfaceStyle {
public:
class ColorComponent {
private:
std::array<double, 3> data;
public:
ColorComponent(double r, double g, double b) {
data[0] = r; data[1] = g; data[2] = b;
}
const double& R() const { return data[0]; }
const double& G() const { return data[1]; }
const double& B() const { return data[2]; }
double& R() { return data[0]; }
double& G() { return data[1]; }
double& B() { return data[2]; }
};
private:
boost::optional<std::string> name;
boost::optional<int> id;
boost::optional<ColorComponent> diffuse, specular;
boost::optional<double> transparency;
boost::optional<double> specularity;
public:
SurfaceStyle() {}
SurfaceStyle(int id) : id(id) {}
SurfaceStyle(const std::string& name) : name(name) {}
SurfaceStyle(int id, const std::string& name) : id(id), name(name) {}
// Not used at this point. In fact, equality testing in the current
// architecture can just as easily be accomplished by comparing the
// pointer addresses of the styles, as they are always referenced
// from out of a global map of some sort.
bool operator==(const SurfaceStyle& other) {
if (name && other.name) {
return *name == *other.name;
} else if (id && other.id) {
return *id == *other.id;
} else {
return false;
}
}
const std::string Name() const {
if (name && id) {
std::stringstream sstr;
sstr << (*id) << "_" << (*name);
return sstr.str();
} else if (name) {
return *name;
} else if (id) {
std::stringstream sstr;
sstr << "IfcSurfaceStyleShading_" << (*id);
return sstr.str();
} else {
return "IfcSurfaceStyleShading";
}
}
const boost::optional<ColorComponent>& Diffuse() const { return diffuse; }
const boost::optional<ColorComponent>& Specular() const { return specular; }
const boost::optional<double>& Transparency() const { return transparency; }
const boost::optional<double>& Specularity() const { return specularity; }
boost::optional<ColorComponent>& Diffuse() { return diffuse; }
boost::optional<ColorComponent>& Specular() { return specular; }
boost::optional<double>& Transparency() { return transparency; }
boost::optional<double>& Specularity() { return specularity; }
};
template <typename T> std::pair<Ifc2x3::IfcSurfaceStyle*, T*> get_surface_style(Ifc2x3::IfcRepresentationItem* representation_item) {
Ifc2x3::IfcStyledItem::list styled_items = representation_item->StyledByItem();
for (Ifc2x3::IfcStyledItem::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
Ifc2x3::IfcPresentationStyleAssignment::list style_assignments = (*jt)->Styles();
for (Ifc2x3::IfcPresentationStyleAssignment::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
IfcAbstractSelect::list styles = (*kt)->Styles();
for (IfcAbstractSelect::it lt = styles->begin(); lt != styles->end(); ++lt) {
IfcAbstractSelect::ptr style = *lt;
if (style->is(Ifc2x3::Type::IfcSurfaceStyle)) {
Ifc2x3::IfcSurfaceStyle* surface_style = (Ifc2x3::IfcSurfaceStyle*) style;
if (surface_style->Side() != Ifc2x3::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
IfcAbstractSelect::list styles_elements = surface_style->Styles();
for (IfcAbstractSelect::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
if ((*mt)->is(T::Class())) {
return std::make_pair(surface_style, (T*) *mt);
}
}
}
}
}
}
// StyledByItem is a SET [0:1] OF IfcStyledItem, so we
// break after encountering the first IfcStyledItem
break;
}
return std::make_pair<Ifc2x3::IfcSurfaceStyle*, T*>(0,0);
}
const SurfaceStyle* get_style(Ifc2x3::IfcRepresentationItem* representation_item);
const SurfaceStyle* get_default_style(const std::string& ifc_type);
namespace Cache {
void PurgeStyleCache();
}
}
#endif
@@ -23,8 +23,28 @@
#include <gp_GTrsf.hxx>
#include <TopoDS_Shape.hxx>
namespace IfcGeom {
typedef std::pair<gp_GTrsf*,const TopoDS_Shape*> LocationShape;
typedef std::vector<LocationShape> ShapeList;
#include "../ifcgeom/IfcGeomRenderStyles.h"
namespace IfcGeom {
class IfcRepresentationShapeItem {
private:
gp_GTrsf placement;
TopoDS_Shape shape;
const SurfaceStyle* style;
public:
IfcRepresentationShapeItem(const gp_GTrsf& placement, const TopoDS_Shape& shape, const SurfaceStyle* style)
: placement(placement), shape(shape), style(style) {}
IfcRepresentationShapeItem(const gp_GTrsf& placement, const TopoDS_Shape& shape)
: placement(placement), shape(shape) {}
IfcRepresentationShapeItem(const TopoDS_Shape& shape, const SurfaceStyle* style)
: shape(shape), style(style) {}
IfcRepresentationShapeItem(const TopoDS_Shape& shape) : shape(shape) {}
void move(const gp_GTrsf& trsf) { placement.Multiply(trsf); }
const TopoDS_Shape& Shape() const { return shape; }
const gp_GTrsf& Placement() const { return placement; }
bool hasStyle() const { return style != 0; }
const SurfaceStyle& Style() const { return *style; }
};
typedef std::vector<IfcRepresentationShapeItem> IfcRepresentationShapeItems;
}
#endif