From 3f048efc79415e80c48611eb5bacb4bdb9e7005e Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sat, 11 May 2013 15:26:35 +0000 Subject: [PATCH] Add an adapter for IfcGeom::SurfaceStyle so that IfcGeomObjects (and most notably the Python wrapper) need not to be aware of boost::optional Expose shading and rendering styles to the Python wrapper as well --- src/ifcconvert/ColladaSerializer.cpp | 62 +++++++++---------- src/ifcconvert/ColladaSerializer.h | 16 ++--- src/ifcconvert/WavefrontObjSerializer.cpp | 36 +++++------ src/ifcconvert/WavefrontObjSerializer.h | 2 +- src/ifcgeom/IfcGeomObjects.cpp | 73 +++++++++++++++-------- src/ifcgeom/IfcGeomObjects.h | 27 +++++++-- src/ifcwrap/IfcPython.i | 38 +++++++++++- src/ifcwrap/Interface.h | 27 ++++++--- 8 files changed, 185 insertions(+), 96 deletions(-) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 3e29fc18ff..311ee65faf 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -49,7 +49,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const source.finish(); } -void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials) { +void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials) { openMesh(mesh_id); // The normals vector can be empty for example when the WELD_VERTICES setting is used. @@ -78,7 +78,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str COLLADASW::Triangles triangles(mSW); triangles.setMaterial(collada_id(previous_material_id == -1 ? default_material_name - : materials[previous_material_id]->Name())); + : materials[previous_material_id].name())); triangles.setCount(num_triangles); int offset = 0; triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) ); @@ -153,23 +153,23 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() { } } -void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::SurfaceStyle* style) { - openEffect(collada_id(style->Name()) + "-fx"); +void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeomObjects::Material& material) { + openEffect(collada_id(material.name()) + "-fx"); COLLADASW::EffectProfile effect(mSW); effect.setShaderType(COLLADASW::EffectProfile::LAMBERT); - if (style->Diffuse()) { - const IfcGeom::SurfaceStyle::ColorComponent& diffuse = *style->Diffuse(); - effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse.R(),diffuse.G(),diffuse.B()))); + if (material.hasDiffuse()) { + const double* diffuse = material.diffuse(); + effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2]))); } - if (style->Specular()) { - const IfcGeom::SurfaceStyle::ColorComponent& specular = *style->Specular(); - effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular.R(),specular.G(),specular.B()))); + if (material.hasSpecular()) { + const double* specular = material.specular(); + effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2]))); } - if (style->Specularity()) { - effect.setShininess(*style->Specularity()); + if (material.hasSpecularity()) { + effect.setShininess(material.specularity()); } - if (style->Transparency()) { - const double transparency = *style->Transparency(); + if (material.hasTransparency()) { + const double transparency = material.transparency(); if (transparency > 0) { effect.setTransparency(transparency); } @@ -182,21 +182,21 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close closeLibrary(); } -void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::SurfaceStyle* style) { - if (!contains(style)) { - effects.write(style); - surface_styles.push_back(style); +void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeomObjects::Material& material) { + if (!contains(material)) { + effects.write(material); + materials.push_back(material); } } -bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::SurfaceStyle* style) { - return std::find(surface_styles.begin(), surface_styles.end(), style) != surface_styles.end(); +bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeomObjects::Material& material) { + return std::find(materials.begin(), materials.end(), material) != materials.end(); } void ColladaSerializer::ColladaExporter::ColladaMaterials::write() { effects.close(); - for (auto it = surface_styles.begin(); it != surface_styles.end(); ++it) { - const std::string& material_name = collada_id((*it)->Name()); + for (auto it = materials.begin(); it != materials.end(); ++it) { + const std::string& material_name = collada_id((*it).name()); openMaterial(material_name); addInstanceEffect("#" + material_name + "-fx"); closeLibrary(); @@ -214,22 +214,22 @@ void ColladaSerializer::ColladaExporter::startDocument() { asset.add(); } -void ColladaSerializer::ColladaExporter::writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& _materials) { - const IfcGeom::SurfaceStyle* default_for_type = IfcGeom::get_default_style(type); +void ColladaSerializer::ColladaExporter::writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& _materials) { + const IfcGeomObjects::Material default_for_type = IfcGeomObjects::Material(IfcGeom::get_default_style(type)); std::vector material_references; const bool needs_default = std::find(material_ids.begin(), material_ids.end(), -1) != material_ids.end(); if (needs_default) { if (!materials.contains(default_for_type)) { materials.add(default_for_type); } - material_references.push_back(collada_id(default_for_type->Name())); + material_references.push_back(collada_id(default_for_type.name())); } - for (std::vector::const_iterator it = _materials.begin(); it != _materials.end(); ++it) { - const IfcGeom::SurfaceStyle* const surface_style_pointer = *it; - if (!materials.contains(surface_style_pointer)) { - materials.add(surface_style_pointer); + for (std::vector::const_iterator it = _materials.begin(); it != _materials.end(); ++it) { + const IfcGeomObjects::Material& material = *it; + if (!materials.contains(material)) { + materials.add(material); } - material_references.push_back(collada_id(surface_style_pointer->Name())); + material_references.push_back(collada_id(material.name())); } deferreds.push_back(DeferredObject(guid, name, type, obj_id, matrix, vertices, normals, indices, material_ids, _materials, material_references)); } @@ -271,7 +271,7 @@ void ColladaSerializer::writeHeader() { void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) { const IfcGeomObjects::IfcRepresentationTriangulation& mesh = o->mesh(); - exporter.writeTesselated(o->guid(), o->name(), o->type(), o->id(), o->matrix(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.materials(), mesh.surface_styles()); + exporter.writeTesselated(o->guid(), o->name(), o->type(), o->id(), o->matrix(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.material_ids(), mesh.materials()); } void ColladaSerializer::finalize() { diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 5ffe248f86..a7813234ea 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -50,7 +50,7 @@ private: : COLLADASW::LibraryGeometries(&stream) {} void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords = "XYZ"); - void write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials); + void write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials); void close(); }; class ColladaScene : public COLLADASW::LibraryVisualScenes @@ -76,18 +76,18 @@ private: explicit ColladaEffects(COLLADASW::StreamWriter& stream) : COLLADASW::LibraryEffects(&stream) {} - void write(const IfcGeom::SurfaceStyle* style); + void write(const IfcGeomObjects::Material& material); void close(); }; - std::vector surface_styles; + std::vector materials; ColladaEffects effects; public: explicit ColladaMaterials(COLLADASW::StreamWriter& stream) : COLLADASW::LibraryMaterials(&stream) , effects(stream) {} - void add(const IfcGeom::SurfaceStyle* style); - bool contains(const IfcGeom::SurfaceStyle* style); + void add(const IfcGeomObjects::Material& material); + bool contains(const IfcGeomObjects::Material& material); void write(); }; class DeferredObject { @@ -99,11 +99,11 @@ private: const std::vector normals; const std::vector indices; const std::vector material_ids; - const std::vector materials; + const std::vector materials; const std::vector material_references; DeferredObject(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, - const std::vector& materials, const std::vector& material_references) + const std::vector& materials, const std::vector& material_references) : guid(guid) , name(name) , type(type) @@ -134,7 +134,7 @@ private: std::vector deferreds; virtual ~ColladaExporter() {} void startDocument(); - void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& materials); + void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& materials); void endDocument(); }; ColladaExporter exporter; diff --git a/src/ifcconvert/WavefrontObjSerializer.cpp b/src/ifcconvert/WavefrontObjSerializer.cpp index 6d56610db1..5d58e4c2f7 100644 --- a/src/ifcconvert/WavefrontObjSerializer.cpp +++ b/src/ifcconvert/WavefrontObjSerializer.cpp @@ -41,21 +41,21 @@ void WaveFrontOBJSerializer::writeHeader() { mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << std::endl; } -void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::SurfaceStyle& style) { - mtl_stream << "newmtl " << style.Name() << std::endl; - if (style.Diffuse()) { - const IfcGeom::SurfaceStyle::ColorComponent& diffuse = *style.Diffuse(); - mtl_stream << "Kd " << diffuse.R() << " " << diffuse.G() << " " << diffuse.B() << std::endl; +void WaveFrontOBJSerializer::writeMaterial(const IfcGeomObjects::Material& style) { + mtl_stream << "newmtl " << style.name() << std::endl; + if (style.hasDiffuse()) { + const double* diffuse = style.diffuse(); + mtl_stream << "Kd " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << std::endl; } - if (style.Specular()) { - const IfcGeom::SurfaceStyle::ColorComponent& specular = *style.Specular(); - mtl_stream << "Ks " << specular.R() << " " << specular.G() << " " << specular.B() << std::endl; + if (style.hasSpecular()) { + const double* specular = style.specular(); + mtl_stream << "Ks " << specular[0] << " " << specular[1] << " " << specular[2] << std::endl; } - if (style.Specularity()) { - mtl_stream << "Ns " << (*style.Specularity()) << std::endl; + if (style.hasSpecularity()) { + mtl_stream << "Ns " << style.specularity() << std::endl; } - if (style.Transparency()) { - const double transparency = 1.0 - *style.Transparency(); + if (style.hasTransparency()) { + const double transparency = 1.0 - style.transparency(); if (transparency < 1) { mtl_stream << "Tr " << transparency << std::endl; mtl_stream << "d " << transparency << std::endl; @@ -85,22 +85,22 @@ void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject } int previous_material_id = -2; - std::vector::const_iterator material_it = mesh.materials().begin(); + std::vector::const_iterator material_it = mesh.material_ids().begin(); for ( std::vector::const_iterator it = mesh.faces().begin(); it != mesh.faces().end(); ) { const int material_id = *(material_it++); if (material_id != previous_material_id) { - const IfcGeom::SurfaceStyle* material_style = 0; + IfcGeomObjects::Material material(0); if (material_id >= 0) { - material_style = mesh.surface_styles()[material_id]; + material = mesh.materials()[material_id]; } else { - material_style = IfcGeom::get_default_style(o->type()); + material = IfcGeomObjects::Material(IfcGeom::get_default_style(o->type())); } - const std::string material_name = material_style->Name(); + const std::string material_name = material.name(); obj_stream << "usemtl " << material_name << std::endl; if (materials.find(material_name) == materials.end()) { - writeMaterial(*material_style); + writeMaterial(material); materials.insert(material_name); } previous_material_id = material_id; diff --git a/src/ifcconvert/WavefrontObjSerializer.h b/src/ifcconvert/WavefrontObjSerializer.h index 5c811b6011..6124c8d5c3 100644 --- a/src/ifcconvert/WavefrontObjSerializer.h +++ b/src/ifcconvert/WavefrontObjSerializer.h @@ -44,7 +44,7 @@ public: virtual ~WaveFrontOBJSerializer() {} bool ready(); void writeHeader(); - void writeMaterial(const IfcGeom::SurfaceStyle& style); + void writeMaterial(const IfcGeomObjects::Material& style); void writeTesselated(const IfcGeomObjects::IfcGeomObject* o); void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {} void finalize() {} diff --git a/src/ifcgeom/IfcGeomObjects.cpp b/src/ifcgeom/IfcGeomObjects.cpp index c20ee6a309..672da0a660 100644 --- a/src/ifcgeom/IfcGeomObjects.cpp +++ b/src/ifcgeom/IfcGeomObjects.cpp @@ -46,12 +46,12 @@ #include "../ifcgeom/IfcGeom.h" // Welds vertices that belong to different faces -bool weld_vertices = true; +static bool weld_vertices = true; -bool convert_back_units = false; -bool use_faster_booleans = false; -bool disable_subtractions = false; -bool disable_triangulation = false; +static bool convert_back_units = false; +static bool use_faster_booleans = false; +static bool disable_subtractions = false; +static bool disable_triangulation = false; int IfcGeomObjects::IfcRepresentationTriangulation::addvert(int material_index, const gp_XYZ& p) { const float X = convert_back_units ? (float) (p.X() / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)) : (float)p.X(); @@ -71,8 +71,8 @@ int IfcGeomObjects::IfcRepresentationTriangulation::addvert(int material_index, return i; } -bool use_world_coords = false; -bool use_brep_data = false; +static bool use_world_coords = false; +static bool use_brep_data = false; static IfcParse::IfcFile* ifc_file = 0; @@ -111,12 +111,13 @@ IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(c int surface_style_id = -1; if (it->hasStyle()) { - std::vector::const_iterator jt = std::find(_surface_styles.begin(), _surface_styles.end(), &it->Style()); - if (jt == _surface_styles.end()) { - surface_style_id = _surface_styles.size(); - _surface_styles.push_back(&it->Style()); + Material adapter(&it->Style()); + std::vector::const_iterator jt = std::find(_materials.begin(), _materials.end(), adapter); + if (jt == _materials.end()) { + surface_style_id = _materials.size(); + _materials.push_back(adapter); } else { - surface_style_id = jt - _surface_styles.begin(); + surface_style_id = jt - _materials.begin(); } } @@ -200,7 +201,7 @@ IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(c _faces.push_back(dict[n2]); _faces.push_back(dict[n3]); - _materials.push_back(surface_style_id); + _material_ids.push_back(surface_style_id); addedge(n1,n2,edgecount,edges_temp); addedge(n2,n3,edgecount,edges_temp); @@ -258,20 +259,20 @@ IfcGeomObjects::IfcGeomObject::IfcGeomObject( {} // A container and iterator for IfcShapeRepresentations -Ifc2x3::IfcShapeRepresentation::list shapereps; -Ifc2x3::IfcShapeRepresentation::it shaperep_iterator; +static Ifc2x3::IfcShapeRepresentation::list shapereps; +static Ifc2x3::IfcShapeRepresentation::it shaperep_iterator; // The object is fetched beforehand to be positive an entity actually exists -IfcGeomObjects::IfcGeomObject* current_geom_obj = 0; -IfcGeomObjects::IfcGeomShapeModelObject* current_shape_model_obj = 0; -IfcGeomObjects::IfcGeomBrepDataObject* current_brep_data_obj = 0; +static IfcGeomObjects::IfcGeomObject* current_geom_obj = 0; +static IfcGeomObjects::IfcGeomShapeModelObject* current_shape_model_obj = 0; +static IfcGeomObjects::IfcGeomBrepDataObject* current_brep_data_obj = 0; // A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *shaperep_iterator -Ifc2x3::IfcProduct::list entities; -Ifc2x3::IfcProduct::it ifcproduct_iterator; +static Ifc2x3::IfcProduct::list entities; +static Ifc2x3::IfcProduct::it ifcproduct_iterator; -int done; -int total; +static int done; +static int total; // Move the the next IfcShapeRepresentation void _nextShape() { @@ -501,7 +502,7 @@ bool IfcGeomObjects::Next() { return try_and_create_representations_for_current_entity(); } -std::vector returned_objects; +static std::vector returned_objects; bool IfcGeomObjects::CleanUp() { // TODO: Correctly implement destructor for IfcFile delete ifc_file; @@ -537,12 +538,18 @@ const IfcGeomObjects::IfcObject* IfcGeomObjects::GetObject(int id) { return ifc_object; } const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() { + if (disable_triangulation) { + throw std::runtime_error("No triangulation available"); + } return current_geom_obj; } const IfcGeomObjects::IfcGeomShapeModelObject* IfcGeomObjects::GetShapeModel() { return current_shape_model_obj; } const IfcGeomObjects::IfcGeomBrepDataObject* IfcGeomObjects::GetBrepData() { + if (!use_brep_data) { + throw std::runtime_error("No BRep data available"); + } return current_brep_data_obj; } double UnitPrefixToValue( Ifc2x3::IfcSIPrefix::IfcSIPrefix v ) { @@ -676,6 +683,7 @@ void IfcGeomObjects::Settings(int setting, bool value) { break; case USE_BREP_DATA: use_brep_data = value; + disable_triangulation = value; break; case FASTER_BOOLEANS: use_faster_booleans = value; @@ -706,6 +714,20 @@ IfcParse::IfcFile* IfcGeomObjects::GetFile() { return ifc_file; } +static double black[3] = {0,0,0}; + +IfcGeomObjects::Material::Material(const IfcGeom::SurfaceStyle* style) : style(style) {} +bool IfcGeomObjects::Material::hasDiffuse() const { return style->Diffuse(); } +bool IfcGeomObjects::Material::hasSpecular() const { return style->Specular(); } +bool IfcGeomObjects::Material::hasTransparency() const { return style->Transparency(); } +bool IfcGeomObjects::Material::hasSpecularity() const { return style->Specularity(); } +const double* IfcGeomObjects::Material::diffuse() const { if (hasDiffuse()) return &((*style->Diffuse()).R()); else return black; } +const double* IfcGeomObjects::Material::specular() const { if (hasSpecular()) return &((*style->Specular()).R()); else return black; } +double IfcGeomObjects::Material::transparency() const { if (hasTransparency()) return *style->Transparency(); else return 0; } +double IfcGeomObjects::Material::specularity() const { if (hasSpecularity()) return *style->Specularity(); else return 0; } +const std::string IfcGeomObjects::Material::name() const { return style->Name(); } +bool IfcGeomObjects::Material::operator==(const IfcGeomObjects::Material& other) const { return style == other.style; } + int IfcGeomObjects::IfcRepresentationBrepData::id() const { return _id; } const std::string& IfcGeomObjects::IfcRepresentationBrepData::brep_data() const { return _brep_data; } @@ -714,8 +736,8 @@ const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::verts( const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::faces() const { return _faces; } const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::edges() const { return _edges; } const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::normals() const { return _normals; } -const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::materials() const { return _materials; } -const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::surface_styles() const { return _surface_styles; } +const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::material_ids() const { return _material_ids; } +const std::vector& IfcGeomObjects::IfcRepresentationTriangulation::materials() const { return _materials; } int IfcGeomObjects::IfcObject::id() const { return _id; } int IfcGeomObjects::IfcObject::parent_id() const { return _parent_id; } @@ -727,3 +749,4 @@ const std::vector& IfcGeomObjects::IfcObject::matrix() const { return _ma const IfcGeomObjects::IfcRepresentationShapeModel& IfcGeomObjects::IfcGeomShapeModelObject::mesh() const { return *_mesh; } const IfcGeomObjects::IfcRepresentationTriangulation& IfcGeomObjects::IfcGeomObject::mesh() const { return *_mesh; } const IfcGeomObjects::IfcRepresentationBrepData& IfcGeomObjects::IfcGeomBrepDataObject::mesh() const { return *_mesh; } + diff --git a/src/ifcgeom/IfcGeomObjects.h b/src/ifcgeom/IfcGeomObjects.h index 722994f580..11d473084c 100644 --- a/src/ifcgeom/IfcGeomObjects.h +++ b/src/ifcgeom/IfcGeomObjects.h @@ -113,6 +113,25 @@ namespace IfcGeomObjects { typedef std::map VertKeyMap; typedef std::pair Edge; + class Material { + private: + const IfcGeom::SurfaceStyle* style; + public: + explicit Material(const IfcGeom::SurfaceStyle* style); + // Material(const Material& other); + // Material& operator=(const Material& other); + bool hasDiffuse() const; + bool hasSpecular() const; + bool hasTransparency() const; + bool hasSpecularity() const; + const double* diffuse() const; + const double* specular() const; + double transparency() const; + double specularity() const; + const std::string name() const; + bool operator==(const Material& other) const; + }; + class IfcRepresentationShapeModel { private: unsigned int id; @@ -152,8 +171,8 @@ namespace IfcGeomObjects { std::vector _faces; std::vector _edges; std::vector _normals; - std::vector _materials; - std::vector _surface_styles; + std::vector _material_ids; + std::vector _materials; VertKeyMap welds; public: int id() const; @@ -161,8 +180,8 @@ namespace IfcGeomObjects { const std::vector& faces() const; const std::vector& edges() const; const std::vector& normals() const; - const std::vector& materials() const; - const std::vector& surface_styles() const; + const std::vector& material_ids() const; + const std::vector& materials() const; IfcRepresentationTriangulation(const IfcRepresentationShapeModel& s); virtual ~IfcRepresentationTriangulation() {} private: diff --git a/src/ifcwrap/IfcPython.i b/src/ifcwrap/IfcPython.i index ebe33c4212..2916903ebe 100644 --- a/src/ifcwrap/IfcPython.i +++ b/src/ifcwrap/IfcPython.i @@ -19,12 +19,30 @@ %include "std_vector.i" %include "std_string.i" +%include "exception.i" + +%typemap(out) const double* { + // This is only used for RGB colours, hence the size of 3 + $result = PyTuple_New(3); + for (int i = 0; i < 3; ++i) { + PyTuple_SetItem($result, i, PyFloat_FromDouble($1[i])); + } +} + +%exception { + try { + $action + } catch(std::runtime_error& e) { + SWIG_exception(SWIG_RuntimeError, e.what()); + } catch(...) { + SWIG_exception(SWIG_RuntimeError, "An unknown error occurred"); + } +} %include "Interface.h" %module IfcImport %{ #include "Interface.h" - using namespace IfcGeom; using namespace IfcGeomObjects; %} @@ -37,6 +55,7 @@ faces = property(faces) edges = property(edges) normals = property(normals) + material_ids = property(material_ids) materials = property(materials) def __repr__(self): return "RepresentationTriangulation #%d"%self.id %} @@ -84,7 +103,24 @@ %} }; +%extend IfcGeomObjects::Material { + %pythoncode %{ + if _newclass: + # Hide the getters with read-only property implementations + has_diffuse = property(hasDiffuse) + has_specular = property(hasSpecular) + has_transparency = property(hasTransparency) + has_specularity = property(hasSpecularity) + diffuse = property(diffuse) + specular = property(specular) + transparency = property(transparency) + specularity = property(specularity) + def __repr__(self): return "Material" + %} +}; + namespace std { %template(IntVector) vector; %template(FloatVector) vector; + %template(MaterialVector) vector; }; \ No newline at end of file diff --git a/src/ifcwrap/Interface.h b/src/ifcwrap/Interface.h index c7a2e61f89..c5b6ff6b16 100644 --- a/src/ifcwrap/Interface.h +++ b/src/ifcwrap/Interface.h @@ -17,11 +17,6 @@ * * ********************************************************************************/ -namespace IfcGeom { - class SurfaceStyle { - }; -} - namespace IfcGeomObjects { const int WELD_VERTICES = 1; @@ -33,6 +28,21 @@ namespace IfcGeomObjects { const int FORCE_CCW_FACE_ORIENTATION = 7; const int DISABLE_OPENING_SUBTRACTIONS = 8; + class Material { + private: + void* style; + public: + bool hasDiffuse() const; + bool hasSpecular() const; + bool hasTransparency() const; + bool hasSpecularity() const; + const double* diffuse() const; + const double* specular() const; + double transparency() const; + double specularity() const; + const std::string name() const; + }; + class IfcRepresentationTriangulation { private: int _id; @@ -40,8 +50,8 @@ namespace IfcGeomObjects { std::vector _faces; std::vector _edges; std::vector _normals; - std::vector _materials; - std::vector _surface_styles; + std::vector _material_ids; + std::vector _materials; IfcRepresentationTriangulation(); IfcRepresentationTriangulation(const IfcRepresentationTriangulation&); @@ -53,7 +63,8 @@ namespace IfcGeomObjects { const std::vector& faces() const; const std::vector& edges() const; const std::vector& normals() const; - const std::vector& materials() const; + const std::vector& material_ids() const; + const std::vector& materials() const; }; class IfcRepresentationBrepData {