diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b956b97c28..35e67c42e0 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -24,7 +24,7 @@ project (IfcOpenShell) OPTION(UNICODE_SUPPORT "Build IfcOpenShell with Unicode support (requires ICU)." ON) OPTION(COLLADA_SUPPORT "Build IfcConvert with COLLADA support (requires OpenCOLLADA)." ON) OPTION(ENABLE_BUILD_OPTIMIZATIONS "Enable certain compiler and linker optimizations on RelWithDebInfo and Release builds." OFF) -#TODO OPTION(IFCCONVERT_DOUBLE_PRECISION "IfcConvert: Use double precision floating-point numbers." OFF) +OPTION(IFCCONVERT_DOUBLE_PRECISION "IfcConvert: Use double precision floating-point numbers." ON) OPTION(USE_IFC4 "Use IFC 4 instead of IFC 2x3 (full rebuild recommended when switching this)" OFF) OPTION(BUILD_IFCPYTHON "Build IfcPython." ON) OPTION(BUILD_EXAMPLES "Build example applications." ON) @@ -397,6 +397,10 @@ if(NOT WIN32) LINK_DIRECTORIES(${LINK_DIRECTORIES} /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64) endif() +# IfcConvert +if (IFCCONVERT_DOUBLE_PRECISION) + add_definitions(-DIFCCONVERT_DOUBLE_PRECISION) +endif() file(GLOB IFCCONVERT_CPP_FILES ../src/ifcconvert/*.cpp) file(GLOB IFCCONVERT_H_FILES ../src/ifcconvert/*.h) set(IFCCONVERT_FILES ${IFCCONVERT_CPP_FILES} ${IFCCONVERT_H_FILES}) diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp index 8dfa39a0c4..c8272aba64 100644 --- a/src/ifcconvert/ColladaSerializer.cpp +++ b/src/ifcconvert/ColladaSerializer.cpp @@ -21,48 +21,63 @@ #include "ColladaSerializer.h" +#include +#include +#include +#include +#include +#include +#include + #include #include +#include -std::string collada_id(const std::string& s) { - std::string id; - id.reserve(s.size()); - for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) { - const std::string::value_type c = *it; - if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || ( c == '-')) { - id.push_back(c); - } - } - return id; +static void collada_id(std::string &s) +{ + IfcUtil::sanitate_material_name(s); + IfcUtil::escape_xml(s); } -void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords /* = "XYZ" */) { +void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, + const std::string& suffix, const std::vector& floats, const char* coords /* = "XYZ" */) +{ COLLADASW::FloatSource source(mSW); source.setId(mesh_id + suffix); source.setArrayId(mesh_id + suffix + COLLADASW::LibraryGeometries::ARRAY_ID_SUFFIX); - source.setAccessorStride((unsigned long)strlen(coords)); - source.setAccessorCount((unsigned long)floats.size() / 3); - for (unsigned int i = 0; i < source.getAccessorStride(); ++i) { + const size_t num_elems = strlen(coords); + source.setAccessorStride(static_cast(num_elems)); + source.setAccessorCount(static_cast(floats.size() / num_elems)); + for (size_t i = 0; i < num_elems; ++i) { source.getParameterNameList().push_back(std::string(1, coords[i])); } source.prepareToAppendValues(); - for (std::vector::const_iterator it = floats.begin(); it != floats.end(); ++it) { + for (std::vector::const_iterator it = floats.begin(); it != floats.end(); ++it) { source.appendValues(*it); } 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& faces, const std::vector& edges, 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& faces, const std::vector& edges, + const std::vector material_ids, const std::vector& materials, + const std::vector& uvs) +{ openMesh(mesh_id); // The normals vector can be empty for example when the WELD_VERTICES setting is used. // IfcOpenShell does not provide them with multiple face normals collapsed into a single vertex. const bool has_normals = !normals.empty(); + const bool has_uvs = !uvs.empty(); addFloatSource(mesh_id, COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX, positions); if (has_normals) { addFloatSource(mesh_id, COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, normals); + if (has_uvs) { + addFloatSource(mesh_id, COLLADASW::LibraryGeometries::TEXCOORDS_SOURCE_ID_SUFFIX, uvs, "UV"); + } } COLLADASW::VerticesElement vertices(mSW); @@ -82,20 +97,28 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str current_material_id = *(material_it++); } - const unsigned long num_triangles = (unsigned long)std::distance(index_range_start, it) / 3; + const size_t num_triangles = std::distance(index_range_start, it) / 3; if ((previous_material_id != current_material_id && num_triangles > 0) || (it == faces.end())) { COLLADASW::Triangles triangles(mSW); - triangles.setMaterial(materials[previous_material_id].name()); - triangles.setCount(num_triangles); + std::string material_name = (serializer->settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? materials[previous_material_id].original_name() : materials[previous_material_id].name()); + collada_id(material_name); + triangles.setMaterial(material_name); + triangles.setCount((unsigned long)num_triangles); int offset = 0; - triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) ); + triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++)); if (has_normals) { - triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::NORMAL,"#" + mesh_id + COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, offset++ ) ); + triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::NORMAL,"#" + mesh_id + COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, offset++)); } + if (has_uvs) { + triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::TEXCOORD,"#" + mesh_id + COLLADASW::LibraryGeometries::TEXCOORDS_SOURCE_ID_SUFFIX, offset++)); + } triangles.prepareToAppendValues(); for (std::vector::const_iterator jt = index_range_start; jt != it; ++jt) { const int idx = *jt; - if (has_normals) { + if (has_normals && has_uvs) { + triangles.appendValues(idx, idx, idx); + } else if(has_normals) { triangles.appendValues(idx, idx); } else { triangles.appendValues(idx); @@ -134,10 +157,13 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str for (linelist_t::const_iterator it = linelist.begin(); it != linelist.end(); ++it) { COLLADASW::Lines lines(mSW); - lines.setMaterial(materials[it->first].name()); + std::string material_name = (serializer->settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? materials[it->first].original_name() : materials[it->first].name()); + collada_id(material_name); + lines.setMaterial(material_name); lines.setCount((unsigned long)it->second.size()); int offset = 0; - lines.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX, "#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++)); + lines.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX, "#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset)); lines.prepareToAppendValues(); lines.appendValues(it->second); lines.finish(); @@ -150,8 +176,11 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str void ColladaSerializer::ColladaExporter::ColladaGeometries::close() { closeLibrary(); } - -void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix) { + +void ColladaSerializer::ColladaExporter::ColladaScene::add( + const std::string& node_id, const std::string& node_name, const std::string& geom_name, + const std::vector& material_ids, const std::vector& matrix) +{ if (!scene_opened) { openVisualScene(scene_id); scene_opened = true; @@ -165,18 +194,24 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& no // The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement. // Note that this placement is absolute, ie it is multiplied with all parent placements. double matrix_array[4][4] = { - {matrix[0], matrix[3], matrix[6], matrix[ 9]}, - {matrix[1], matrix[4], matrix[7], matrix[10]}, - {matrix[2], matrix[5], matrix[8], matrix[11]}, - { 0, 0, 0, 1} + { (double)matrix[0], (double)matrix[3], (double)matrix[6], (double)matrix[ 9] }, + { (double)matrix[1], (double)matrix[4], (double)matrix[7], (double)matrix[10] }, + { (double)matrix[2], (double)matrix[5], (double)matrix[8], (double)matrix[11] }, + { 0, 0, 0, 1 } }; + matrix_array[0][3] += serializer->settings().offset[0]; + matrix_array[1][3] += serializer->settings().offset[1]; + matrix_array[2][3] += serializer->settings().offset[2]; + node.start(); node.addMatrix(matrix_array); COLLADASW::InstanceGeometry instanceGeometry(mSW); instanceGeometry.setUrl ("#" + geom_name); - for (std::vector::const_iterator it = material_ids.begin(); it != material_ids.end(); ++it) { - COLLADASW::InstanceMaterial material (*it, "#" + *it); + foreach(std::string material_name, material_ids) { + /// @todo This is done 6 times in this file, try to perform this once and be done with the material naming for the export. + collada_id(material_name); + COLLADASW::InstanceMaterial material (material_name, "#" + material_name); instanceGeometry.getBindMaterial().getInstanceMaterialList().push_back(material); } instanceGeometry.add(); @@ -192,9 +227,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() { scene.add(); } } - -void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material) { - openEffect(collada_id(material.name()) + "-fx"); + +void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material) +{ + std::string material_name = (serializer->settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + collada_id(material_name); + openEffect(material_name + "-fx"); COLLADASW::EffectProfile effect(mSW); effect.setShaderType(COLLADASW::EffectProfile::LAMBERT); if (material.hasDiffuse()) { @@ -223,7 +262,7 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close() { closeLibrary(); } - + void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) { if (!contains(material)) { effects.write(material); @@ -237,15 +276,19 @@ bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeo void ColladaSerializer::ColladaExporter::ColladaMaterials::write() { effects.close(); - for (std::vector::const_iterator it = materials.begin(); it != materials.end(); ++it) { - const std::string& material_name = collada_id((*it).name()); + foreach(const IfcGeom::Material& material, materials) { + std::string material_name = (serializer->settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + std::string material_name_unescaped = material_name; // workaround double-escaping that would occur in addInstanceEffect() + IfcUtil::sanitate_material_name(material_name_unescaped); + collada_id(material_name); openMaterial(material_name); - addInstanceEffect("#" + material_name + "-fx"); + addInstanceEffect("#" + material_name_unescaped + "-fx"); closeMaterial(); } closeLibrary(); } - + void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_name, float unit_magnitude) { stream.startDocument(); @@ -256,16 +299,28 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n asset.add(); } -void ColladaSerializer::ColladaExporter::write(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& _materials) { +void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o) +{ + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + const std::string name = serializer->settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_GUIDS) ? + o->guid() : (serializer->settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_NAMES) ? o->name() : o->unique_id()); + const std::string representation_id = "representation-" + boost::lexical_cast(o->geometry().id()); + std::vector material_references; - for (std::vector::const_iterator it = _materials.begin(); it != _materials.end(); ++it) { - const IfcGeom::Material& material = *it; + foreach(const IfcGeom::Material& material, mesh.materials()) { if (!materials.contains(material)) { materials.add(material); } - material_references.push_back(collada_id(material.name())); + std::string material_name = (serializer->settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + collada_id(material_name); + material_references.push_back(material_name); } - deferreds.push_back(DeferredObject(unique_id, representation_id, type, matrix, vertices, normals, faces, edges, material_ids, _materials, material_references)); + + deferreds.push_back( + DeferredObject(name, representation_id, o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), + mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs()) + ); } void ColladaSerializer::ColladaExporter::endDocument() { @@ -278,7 +333,7 @@ void ColladaSerializer::ColladaExporter::endDocument() { continue; } geometries_written.insert(it->representation_id); - geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials); + geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs); } geometries.close(); for (std::vector::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { @@ -288,7 +343,7 @@ void ColladaSerializer::ColladaExporter::endDocument() { scene.write(); stream.endDocument(); } - + bool ColladaSerializer::ready() { return true; } @@ -297,9 +352,8 @@ void ColladaSerializer::writeHeader() { exporter.startDocument(unit_name, unit_magnitude); } -void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { - const IfcGeom::Representation::Triangulation& mesh = o->geometry(); - exporter.write(o->unique_id(), "representation-" + boost::lexical_cast(o->geometry().id()), o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials()); +void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) { + exporter.write(o); } void ColladaSerializer::finalize() { diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index b8e5059e62..11f06381a1 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -27,17 +27,10 @@ #pragma warning(disable : 4201 4512) #endif #include -#include #include -#include -#include -#include -#include #include #include #include -#include -#include #ifdef _MSC_VER #pragma warning(pop) #endif @@ -58,12 +51,19 @@ private: ColladaGeometries(const ColladaGeometries&); //N/A ColladaGeometries& operator =(const ColladaGeometries&); //N/A public: - explicit ColladaGeometries(COLLADASW::StreamWriter& stream) + explicit ColladaGeometries(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryGeometries(&stream) + , serializer(_serializer) {} - 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& faces, const std::vector& edges, const std::vector material_ids, const std::vector& materials); + 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& faces, const std::vector& edges, + const std::vector material_ids, const std::vector& materials, + const std::vector& uvs); void close(); + ColladaSerializer *serializer; }; class ColladaScene : public COLLADASW::LibraryVisualScenes { @@ -74,13 +74,16 @@ private: const std::string scene_id; bool scene_opened; public: - ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream) + ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryVisualScenes(&stream) , scene_id(scene_id) - , scene_opened(false) + , scene_opened(false) + , serializer(_serializer) {} - void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix); + void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, + const std::vector& material_ids, const std::vector& matrix); void write(); + ColladaSerializer *serializer; }; class ColladaMaterials : public COLLADASW::LibraryMaterials { @@ -97,32 +100,37 @@ private: {} void write(const IfcGeom::Material& material); void close(); + ColladaSerializer *serializer; }; std::vector materials; - ColladaEffects effects; public: - explicit ColladaMaterials(COLLADASW::StreamWriter& stream) + explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryMaterials(&stream) , effects(stream) + , serializer(_serializer) {} void add(const IfcGeom::Material& material); bool contains(const IfcGeom::Material& material); void write(); + ColladaSerializer *serializer; + ColladaEffects effects; }; class DeferredObject { public: std::string unique_id, representation_id, type; - std::vector matrix; - std::vector vertices; - std::vector normals; + std::vector matrix; + std::vector vertices; + std::vector normals; std::vector faces; std::vector edges; std::vector material_ids; std::vector materials; std::vector material_references; - DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, - const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, - const std::vector& materials, const std::vector& material_references) + std::vector uvs; + DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, + const std::vector& vertices, const std::vector& normals, const std::vector& faces, + const std::vector& edges, const std::vector& material_ids, const std::vector& materials, + const std::vector& material_references, const std::vector& uvs) : unique_id(unique_id) , representation_id(representation_id) , type(type) @@ -134,39 +142,48 @@ private: , material_ids(material_ids) , materials(materials) , material_references(material_references) + , uvs(uvs) {} }; COLLADABU::NativeString filename; COLLADASW::StreamWriter stream; - ColladaGeometries geometries; ColladaScene scene; - ColladaMaterials materials; public: - ColladaExporter(const std::string& scene_name, const std::string& fn) - : filename(fn.c_str()) - , stream(filename) - , geometries(stream) - , scene(scene_name, stream) - , materials(stream) - {} + ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer) + : filename(fn) + , stream(filename, sizeof(real_t) == sizeof(double)) // utilise Collada stream's double precision feature + , geometries(stream, _serializer) + , scene(scene_name, stream, _serializer) + , materials(stream, _serializer) + , serializer(_serializer) + { + } + ColladaMaterials materials; + ColladaSerializer *serializer; + ColladaGeometries geometries; std::vector deferreds; virtual ~ColladaExporter() {} void startDocument(const std::string& unit_name, float unit_magnitude); - void write(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& materials); + void write(const IfcGeom::TriangulationElement* o); void endDocument(); }; ColladaExporter exporter; std::string unit_name; float unit_magnitude; public: - ColladaSerializer(const std::string& dae_filename) - : GeometrySerializer() - , exporter("IfcOpenShell", dae_filename) - {} + ColladaSerializer(const std::string& dae_filename, const IfcGeom::IteratorSettings &settings) + : GeometrySerializer(settings) + , exporter("IfcOpenShell", dae_filename, this) + { + exporter.serializer = this; + exporter.materials.serializer = this; + exporter.materials.effects.serializer = this; + exporter.geometries.serializer = this; + } bool ready(); void writeHeader(); - void write(const IfcGeom::TriangulationElement* o); - void write(const IfcGeom::BRepElement* /*o*/) {} + void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::BRepElement* /*o*/) {} void finalize(); bool isTesselated() const { return true; } void setUnitNameAndMagnitude(const std::string& name, float magnitude) { diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 0a62defa18..c2ee0f6416 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -20,17 +20,30 @@ #ifndef GEOMETRYSERIALIZER_H #define GEOMETRYSERIALIZER_H +#ifdef IFCCONVERT_DOUBLE_PRECISION +typedef double real_t; +#else +typedef float real_t; +#endif + #include "../ifcconvert/Serializer.h" #include "../ifcgeom/IfcGeomIterator.h" class GeometrySerializer : public Serializer { public: + GeometrySerializer(const IfcGeom::IteratorSettings &settings) : settings_(settings) {} virtual ~GeometrySerializer() {} virtual bool isTesselated() const = 0; - virtual void write(const IfcGeom::TriangulationElement* o) = 0; - virtual void write(const IfcGeom::BRepElement* o) = 0; + virtual void write(const IfcGeom::TriangulationElement* o) = 0; + virtual void write(const IfcGeom::BRepElement* o) = 0; virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0; + + const IfcGeom::IteratorSettings& settings() const { return settings_; } + IfcGeom::IteratorSettings& settings() { return settings_; } + +protected: + IfcGeom::IteratorSettings settings_; }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 8f1e285ea8..8f77d82ce3 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -26,16 +26,6 @@ * * ********************************************************************************/ -#include -#include -#include -#include - -#include -#include - -#include "../ifcgeom/IfcGeomIterator.h" - #include "../ifcconvert/ColladaSerializer.h" #include "../ifcconvert/IgesSerializer.h" #include "../ifcconvert/StepSerializer.h" @@ -43,35 +33,58 @@ #include "../ifcconvert/XmlSerializer.h" #include "../ifcconvert/SvgSerializer.h" +#include "../ifcgeom/IfcGeomIterator.h" + #include #include +#include +#include +#include + +#include +#include +#include +#include + #if USE_VLD #include #endif -static std::string DEFAULT_EXTENSION = "obj"; +const std::string DEFAULT_EXTENSION = "obj"; +const std::string TEMP_FILE_EXTENSION = ".tmp"; -void printVersion() { - std::cerr << "IfcOpenShell IfcConvert " << IFCOPENSHELL_VERSION << std::endl; +void print_version() +{ + /// @todo Why cerr used for info prints? Change to cout. + std::cerr << "IfcOpenShell " << IfcSchema::Identifier << " IfcConvert " << IFCOPENSHELL_VERSION << std::endl; } -void printUsage(const boost::program_options::options_description& generic_options, const boost::program_options::options_description& geom_options) { - printVersion(); - std::cerr << "Usage: IfcConvert [options] []" << std::endl - << std::endl - << "Converts the geometry in an IFC file into one of the following formats:" << std::endl - << " .obj WaveFront OBJ (a .mtl file is also created)" << std::endl; -#ifdef WITH_OPENCOLLADA - std::cerr << " .dae Collada Digital Asset Exchange" << std::endl; +void print_usage(bool suggest_help = true) +{ + std::cerr << "Usage: IfcConvert [options] []" << "\n" + << "\n" + << "Converts the geometry in an IFC file into one of the following formats:" << "\n" + << " .obj WaveFront OBJ (a .mtl file is also created)" << "\n" +#ifdef WITH_OPENCOLLADA + << " .dae Collada Digital Assets Exchange" << "\n" #endif - std::cerr << " .stp STEP Standard for the Exchange of Product Data" << std::endl - << " .igs IGES Initial Graphics Exchange Specification" << std::endl - << " .xml XML Property definitions and decomposition tree" << std::endl - << " .svg SVG Scalable Vector Graphics (2d floor plan)" << std::endl - << std::endl - << "Command line options" << std::endl << generic_options << std::endl - << "Advanced options" << std::endl << geom_options << std::endl; + << " .stp STEP Standard for the Exchange of Product Data" << "\n" + << " .igs IGES Initial Graphics Exchange Specification" << "\n" + << " .xml XML Property definitions and decomposition tree" << "\n" + << " .svg SVG Scalable Vector Graphics (2D floor plan)" << "\n" + << "\n" + << "If no output filename given, ." + DEFAULT_EXTENSION + " will be used as the output file.\n"; + if (suggest_help) { + std::cerr << "\nRun 'IfcConvert --help' for more information."; + } + std::cerr << std::endl; +} + +void print_options(const boost::program_options::options_description& options) +{ + std::cerr << "\n" << options; + std::cerr << std::endl; } std::string change_extension(const std::string& fn, const std::string& ext) { @@ -83,24 +96,41 @@ std::string change_extension(const std::string& fn, const std::string& ext) { } } +bool file_exists(const std::string& filename) +{ + /// @todo Windows Unicode support + std::ifstream file(filename.c_str()); + return file.good(); +} + +bool rename_file(const std::string& old_filename, const std::string& new_filename) +{ + // Whether or not rename() replaces an existing file is implementation-specific, + // so remove() possible existing file always. + /// @todo Windows Unicode support + std::remove(new_filename.c_str()); + return std::rename(old_filename.c_str(), new_filename.c_str()) == 0; +} + static std::stringstream log_stream; void write_log(); int main(int argc, char** argv) { - boost::program_options::options_description generic_options; + boost::program_options::options_description generic_options("Command line options"); generic_options.add_options() - ("help", "display usage information") + ("help,h", "display usage information") ("version", "display version information") - ("verbose,v", "more verbose output"); + ("verbose,v", "more verbose output") + ("yes,y", "answer 'yes' automatically to possible confirmation queries (e.g overwriting an existing output file)"); boost::program_options::options_description fileio_options; fileio_options.add_options() ("input-file", boost::program_options::value(), "input IFC file") ("output-file", boost::program_options::value(), "output geometry file"); - std::string bounds; - std::vector entity_vector; - boost::program_options::options_description geom_options; + std::vector entity_vector, names; + double deflection_tolerance; + boost::program_options::options_description geom_options("Geometry options"); geom_options.add_options() ("plan", "Specifies whether to include curves in the output result. Typically " @@ -142,20 +172,51 @@ int main(int argc, char** argv) { ("disable-opening-subtractions", "Specifies whether to disable the boolean subtraction of " "IfcOpeningElement Representations from their RelatingElements.") - ("bounds", boost::program_options::value(&bounds), - "Specifies the bounding rectangle, for example 512x512, to which the " - "output will be scaled. Only used when converting to SVG.") ("include", - "Specifies that the entities listed after --entities are to be included") + "Specifies that the entities listed after --entities or --names are to be included") ("exclude", - "Specifies that the entities listed after --entities are to be excluded") - ("entities", boost::program_options::value< std::vector >(&entity_vector)->multitoken(), + "Specifies that the entities listed after --entities or --names are to be excluded") + ("entities", boost::program_options::value< std::vector >(&entity_vector)->multitoken(), "A list of entities that should be included in or excluded from the " - "geometrical output, depending on whether --ignore or --include is " - "specified. Defaults to IfcOpeningElement and IfcSpace to be excluded."); - + "geometrical output, depending on whether --exclude or --include is specified. " + "Defaults to IfcOpeningElement and IfcSpace to be excluded. SVG output defaults " + "to IfcSpace to be included." + "The names are handled case-insensitively. Cannot be placed right before input file argument.") + ("names", boost::program_options::value< std::vector >(&names)->multitoken(), + "A list of names or wildcard patterns that should be included in or excluded from the " + "geometrical output, depending on whether --exclude or --include is specified. " + "The names are handled case-sensitively. Cannot be placed right before input file argument.") + ("no-normals", + "Disables computation of normals. Saves time and file size and is useful " + "in instances where you're going to recompute normals for the exported " + "model in other modelling application in any case.") + ("deflection-tolerance", boost::program_options::value(&deflection_tolerance), + "Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.") + ("generate-uvs", + "Generates UVs (texture coordinates) by using simple box projection. Requires normals. " + "Not guaranteed to work properly if used with --weld-vertices."); + + std::string bounds; + boost::program_options::options_description serializer_options("Serialization options"); + serializer_options.add_options() + ("bounds", boost::program_options::value(&bounds), + "Specifies the bounding rectangle, for example 512x512, to which the " + "output will be scaled. Only used when converting to SVG.") + ("use-element-names", + "Use entity names instead of unique IDs for naming elements upon serialization. " + "Applicable for OBJ, DAE, and SVG output.") + ("use-element-guids", + "Use entity GUIDs instead of unique IDs for naming elements upon serialization. " + "Applicable for OBJ, DAE, and SVG output.") + ("use-material-names", + "Use material names instead of unique IDs for naming materials upon serialization. " + "Applicable for OBJ and DAE output.") + ("center-model", + "Centers the elements upon serialization by applying the center point of " + "all placements as an offset. Applicable for OBJ and DAE output."); + boost::program_options::options_description cmdline_options; - cmdline_options.add(generic_options).add(fileio_options).add(geom_options); + cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(serializer_options); boost::program_options::positional_options_description positional_options; positional_options.add("input-file", 1); @@ -167,21 +228,30 @@ int main(int argc, char** argv) { options(cmdline_options).positional(positional_options).run(), vmap); } catch (const boost::program_options::unknown_option& e) { std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'" << std::endl << std::endl; - // Usage information will be emitted below + print_usage(); + return 1; } catch (...) { // Catch other errors such as invalid command line syntax + print_usage(); + return 1; } boost::program_options::notify(vmap); - if (vmap.count("version")) { - printVersion(); - return 0; - } else if (vmap.count("help") || !vmap.count("input-file")) { - printUsage(generic_options, geom_options); - return vmap.count("help") ? 0 : 1; + print_version(); + + if (vmap.count("version")) { + return 0; + } else if (vmap.count("help")) { + print_usage(false); + print_options(generic_options.add(geom_options).add(serializer_options)); + return 0; + } else if (!vmap.count("input-file")) { + std::cerr << "[Error] Input file not specified" << std::endl; + print_usage(); + return 1; } else if (vmap.count("include") && vmap.count("exclude")) { - std::cerr << "[Error] --include and --ignore can not be specified together" << std::endl; - printUsage(generic_options, geom_options); + std::cerr << "[Error] --include and --exclude can not be specified together" << std::endl; + print_options(geom_options); return 1; } @@ -197,6 +267,13 @@ int main(int argc, char** argv) { bool include_entities = vmap.count("include") != 0; const bool include_plan = vmap.count("plan") != 0; const bool include_model = vmap.count("model") != 0 || (!include_plan); + const bool use_element_names = vmap.count("use-element-names") != 0; + const bool use_element_guids = vmap.count("use-element-guids") != 0 ; + const bool use_material_names = vmap.count("use-material-names") != 0; + const bool no_normals = vmap.count("no-normals") != 0 ; + bool center_model = vmap.count("center-model") != 0 ; + const bool generate_uvs = vmap.count("generate-uvs") != 0 ; + const bool deflection_tolerance_specified = vmap.count("deflection-tolerance") != 0 ; boost::optional bounding_width, bounding_height; if (vmap.count("bounds") == 1) { int w, h; @@ -205,19 +282,20 @@ int main(int argc, char** argv) { bounding_height = h; } else { std::cerr << "[Error] Invalid use of --bounds" << std::endl; - printUsage(generic_options, geom_options); + print_options(serializer_options); return 1; } } // Gets the set ifc types to be ignored from the command line. - std::set entities; - for (std::vector::const_iterator it = entity_vector.begin(); it != entity_vector.end(); ++it) { - const std::string& mixed_case_type = *it; - entities.insert(boost::to_lower_copy(mixed_case_type)); - } - + std::set entities(entity_vector.begin(), entity_vector.end()); + const std::string input_filename = vmap["input-file"].as(); + if (!file_exists(input_filename)) { + std::cerr << "[Error] Input file '" << input_filename << "' does not exist" << std::endl; + return 1; + } + // If no output filename is specified a Wavefront OBJ file will be output // to maintain backwards compatibility with the obsolete IfcObj executable. const std::string output_filename = vmap.count("output-file") == 1 @@ -225,21 +303,32 @@ int main(int argc, char** argv) { : change_extension(input_filename, DEFAULT_EXTENSION); if (output_filename.size() < 5) { - printUsage(generic_options, geom_options); + std::cerr << "[Error] Invalid or unsupported output file '" << output_filename << "' given" << std::endl; + print_usage(); return 1; } + if (file_exists(output_filename) && !vmap.count("yes")) { + std::string answer; + std::cout << "A file '" << output_filename << "' already exists. Overwrite the existing file?" << std::endl; + std::cin >> answer; + if (!boost::iequals(answer, "yes") && !boost::iequals(answer, "y")) { + return 0; + } + } + + std::string output_temp_filename = output_filename + TEMP_FILE_EXTENSION; + std::string output_extension = output_filename.substr(output_filename.size()-4); boost::to_lower(output_extension); - // If no entities are specified these are the defaults to skip from output - if (entity_vector.empty()) { + // If no entity or names filters are specified these are the defaults to skip from output + if (entities.empty() && names.empty()) { + entities.insert("IfcSpace"); if (output_extension == ".svg") { - entities.insert("ifcspace"); include_entities = true; } else { - entities.insert("ifcopeningelement"); - entities.insert("ifcspace"); + entities.insert("IfcOpeningElement"); } } @@ -249,13 +338,14 @@ int main(int argc, char** argv) { if (output_extension == ".xml") { int exit_code = 1; try { - XmlSerializer s(output_filename); + XmlSerializer s(output_temp_filename); IfcParse::IfcFile f; if (!f.Init(input_filename)) { - Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file"); + Logger::Message(Logger::LOG_ERROR, "Unable to parse input file '" + input_filename + "'"); } else { s.setFile(&f); s.finalize(); + rename_file(output_temp_filename, output_filename); exit_code = 0; } } catch (...) {} @@ -264,7 +354,7 @@ int main(int argc, char** argv) { } IfcGeom::IteratorSettings settings; - + /// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn. settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true); settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, use_world_coords); settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices); @@ -276,56 +366,70 @@ int main(int argc, char** argv) { settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions); settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, include_plan); settings.set(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES, !include_model); + settings.set(IfcGeom::IteratorSettings::USE_ELEMENT_NAMES, use_element_names); + settings.set(IfcGeom::IteratorSettings::USE_ELEMENT_GUIDS, use_element_guids); + settings.set(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES, use_material_names); + settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals); + settings.set(IfcGeom::IteratorSettings::CENTER_MODEL, center_model); + settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs); + if (deflection_tolerance_specified) { + settings.set_deflection_tolerance(deflection_tolerance); + } GeometrySerializer* serializer; if (output_extension == ".obj") { - const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl"; + const std::string mtl_temp_filename = change_extension(output_filename, "mtl") + TEMP_FILE_EXTENSION; if (!use_world_coords) { Logger::Message(Logger::LOG_NOTICE, "Using world coords when writing WaveFront OBJ files"); settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true); } - serializer = new WaveFrontOBJSerializer(output_filename, mtl_filename); + serializer = new WaveFrontOBJSerializer(output_temp_filename, mtl_temp_filename, settings); #ifdef WITH_OPENCOLLADA } else if (output_extension == ".dae") { - serializer = new ColladaSerializer(output_filename); + serializer = new ColladaSerializer(output_temp_filename, settings); #endif } else if (output_extension == ".stp") { - serializer = new StepSerializer(output_filename); + serializer = new StepSerializer(output_temp_filename, settings); } else if (output_extension == ".igs") { - // Not sure why this is needed, but it is. - // See: http://tracker.dev.opencascade.org/view.php?id=23679 - IGESControl_Controller::Init(); - serializer = new IgesSerializer(output_filename); + IGESControl_Controller::Init(); // work around Open Cascade bug + serializer = new IgesSerializer(output_temp_filename, settings); } else if (output_extension == ".svg") { settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); - serializer = new SvgSerializer(output_filename); + serializer = new SvgSerializer(output_temp_filename, settings); if (bounding_width && bounding_height) { - ((SvgSerializer*) serializer)->setBoundingRectangle( - static_cast(*bounding_width), - static_cast(*bounding_height) - ); + static_cast(serializer)->setBoundingRectangle(*bounding_width, *bounding_height); } } else { - Logger::Message(Logger::LOG_ERROR, "Unknown output filename extension"); + Logger::Message(Logger::LOG_ERROR, "Unknown output filename extension '" + output_extension + "'"); write_log(); - printUsage(generic_options, geom_options); + print_usage(); return 1; } - if (!serializer->isTesselated()) { + const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time + if (!is_tesselated) { if (weld_vertices) { - Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing STEP or IGES files"); + Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing non-tesselated output"); } - settings.disable_triangulation() = true; + if (generate_uvs) { + Logger::Message(Logger::LOG_NOTICE, "Generate UVs setting ignored when writing non-tesselated output"); + } + if (center_model) { + Logger::Message(Logger::LOG_NOTICE, "Center model setting ignored when writing non-tesselated output"); + } + + settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); } - IfcGeom::Iterator context_iterator(settings, input_filename); + IfcGeom::Iterator context_iterator(settings, input_filename); try { if (include_entities) { context_iterator.includeEntities(entities); + context_iterator.include_entity_names(names); } else { context_iterator.excludeEntities(entities); + context_iterator.exclude_entity_names(names); } } catch (const IfcParse::IfcException& e) { std::cout << "[Error] " << e.what() << std::endl; @@ -333,7 +437,7 @@ int main(int argc, char** argv) { } if (!serializer->ready()) { - Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing"); + Logger::Message(Logger::LOG_ERROR, "Unable to open output '" + output_filename + "' file for writing"); write_log(); return 1; } @@ -342,26 +446,25 @@ int main(int argc, char** argv) { time(&start); if (!context_iterator.initialize()) { - Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file or no geometrical entities found"); + Logger::Message(Logger::LOG_ERROR, "Unable to parse input file '" + input_filename + "' or no geometrical entities found"); write_log(); return 1; } - serializer->setFile(context_iterator.getFile()); + serializer->setFile(context_iterator.getFile()); if (convert_back_units) { - serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude())); + serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude())); } else { serializer->setUnitNameAndMagnitude("METER", 1.0f); } serializer->writeHeader(); - std::set materials; - int old_progress = -1; Logger::Status("Creating geometry..."); + std::vector* > geometries; // The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next() // wrap an iterator of all geometrical products in the Ifc file. // IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or @@ -373,30 +476,60 @@ int main(int argc, char** argv) { // true return value guarantees that a successfully processed product is // available. do { - const IfcGeom::Element* geom_object = context_iterator.get(); - - if (serializer->isTesselated()) { - serializer->write(static_cast*>(geom_object)); - } else { - serializer->write(static_cast*>(geom_object)); - } - - const int progress = context_iterator.progress() / 2; - if (old_progress!= progress) Logger::ProgressBar(progress); - old_progress = progress; - - } while (context_iterator.next()); + IfcGeom::Element *geom_object = context_iterator.get(true); // true == take ownership, we will clean up ourselves + geometries.push_back(geom_object); + const int progress = context_iterator.progress() / 2; + if (old_progress != progress) Logger::ProgressBar(progress); + old_progress = progress; + } while (context_iterator.next()); + + Logger::Status("\rDone creating geometry (" + boost::lexical_cast(geometries.size()) + + " objects) "); + + if (center_model) { + double* offset = serializer->settings().offset; + gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5; + offset[0] = -center.X(); + offset[1] = -center.Y(); + offset[2] = -center.Z(); + //printf("Bounds min. (%g, %g, %g)\n", context_iterator.bounds_min().X(), context_iterator.bounds_min().Y(), context_iterator.bounds_min().Z()); + //printf("Bounds max. (%g, %g, %g)\n", context_iterator.bounds_min().X(), context_iterator.bounds_min().X(), context_iterator.bounds_min().Z()); + printf("Using model offset (%g, %g, %g)\n", offset[0], offset[1], offset[2]); //TODO Logger::Message(Logger::LOG_NOTICE, ...); + } + + Logger::Status("Serializing geometry..."); + + foreach(const IfcGeom::Element* geom, geometries) { + if (is_tesselated) { + serializer->write(static_cast*>(geom)); + } else { + serializer->write(static_cast*>(geom)); + } + delete geom; + } serializer->finalize(); + + Logger::Status("\rDone serializing geometry "); + delete serializer; - Logger::Status("\rDone creating geometry "); + rename_file(output_temp_filename, output_filename); + + if (output_extension == ".obj") { + std::string mtl_filename = change_extension(output_filename, "mtl"); + std::string mtl_tmp_filename = mtl_filename + TEMP_FILE_EXTENSION; + rename_file(mtl_tmp_filename, mtl_filename); + } write_log(); time(&end); - int dif = (int) difftime (end,start); - printf ("\nConversion took %d seconds\n", dif ); + int seconds = (int)difftime(end, start); + if (seconds < 60) + printf("\nConversion took %d seconds\n", seconds); // TODO Logger::Message(Logger::LOG_NOTICE, ...); + else + printf("\nConversion took %d minute(s) %d seconds\n", seconds/60, seconds%60); // TODO Logger::Message(Logger::LOG_NOTICE, ...); return 0; } @@ -404,7 +537,6 @@ int main(int argc, char** argv) { void write_log() { std::string log = log_stream.str(); if (!log.empty()) { - std::cerr << std::endl << "Log:" << std::endl; - std::cerr << log << std::endl; + std::cerr << "\n" << "Log:\n" << log << std::endl; } -} \ No newline at end of file +} diff --git a/src/ifcconvert/IgesSerializer.h b/src/ifcconvert/IgesSerializer.h index 5e11e7b324..fb8045c2de 100644 --- a/src/ifcconvert/IgesSerializer.h +++ b/src/ifcconvert/IgesSerializer.h @@ -20,20 +20,20 @@ #ifndef IGESSERIALIZER_H #define IGESSERIALIZER_H +#include "OpenCascadeBasedSerializer.h" + #include #include -#include "../ifcgeom/IfcGeomIterator.h" - -#include "../ifcconvert/OpenCascadeBasedSerializer.h" - class IgesSerializer : public OpenCascadeBasedSerializer { private: - IGESControl_Writer writer; + IGESControl_Writer writer; public: - explicit IgesSerializer(const std::string& out_filename) - : OpenCascadeBasedSerializer(out_filename) + /// @note IGESControl_Controller::Init() must be called prior to instantiating IgesSerializer. + /// See http://tracker.dev.opencascade.org/view.php?id=23679 for more information. + IgesSerializer(const std::string& out_filename, const IfcGeom::IteratorSettings &settings) + : OpenCascadeBasedSerializer(out_filename, settings) {} virtual ~IgesSerializer() {} void writeShape(const TopoDS_Shape& shape) { @@ -51,4 +51,4 @@ public: } }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.cpp b/src/ifcconvert/OpenCascadeBasedSerializer.cpp index 2dbb642c3d..1400d7c400 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.cpp +++ b/src/ifcconvert/OpenCascadeBasedSerializer.cpp @@ -36,14 +36,14 @@ bool OpenCascadeBasedSerializer::ready() { return succeeded; } -void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) { +void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) { for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) { gp_GTrsf gtrsf = it->Placement(); const gp_Trsf& o_trsf = o->transformation().data(); gtrsf.PreMultiply(o_trsf); - if (o->geometry().settings().convert_back_units()) { + if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude()); gtrsf.PreMultiply(scale); diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.h b/src/ifcconvert/OpenCascadeBasedSerializer.h index 6ee69635a4..f36a844609 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.h +++ b/src/ifcconvert/OpenCascadeBasedSerializer.h @@ -31,18 +31,18 @@ protected: const std::string out_filename; const char* getSymbolForUnitMagnitude(float mag); public: - explicit OpenCascadeBasedSerializer(const std::string& out_filename) - : GeometrySerializer() + explicit OpenCascadeBasedSerializer(const std::string& out_filename, const IfcGeom::IteratorSettings &settings) + : GeometrySerializer(settings) , out_filename(out_filename) {} virtual ~OpenCascadeBasedSerializer() {} void writeHeader() {} bool ready(); virtual void writeShape(const TopoDS_Shape& shape) = 0; - void write(const IfcGeom::TriangulationElement* /*o*/) {} - void write(const IfcGeom::BRepElement* o); + void write(const IfcGeom::TriangulationElement* /*o*/) {} + void write(const IfcGeom::BRepElement* o); bool isTesselated() const { return false; } void setFile(IfcParse::IfcFile*) {} }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcconvert/StepSerializer.h b/src/ifcconvert/StepSerializer.h index ff53fa4ae4..99fff685b8 100644 --- a/src/ifcconvert/StepSerializer.h +++ b/src/ifcconvert/StepSerializer.h @@ -32,8 +32,8 @@ class StepSerializer : public OpenCascadeBasedSerializer private: STEPControl_Writer writer; public: - explicit StepSerializer(const std::string& out_filename) - : OpenCascadeBasedSerializer(out_filename) + explicit StepSerializer(const std::string& out_filename, const IfcGeom::IteratorSettings &settings) + : OpenCascadeBasedSerializer(out_filename, settings) {} virtual ~StepSerializer() {} void writeShape(const TopoDS_Shape& shape) { diff --git a/src/ifcconvert/SvgSerializer.cpp b/src/ifcconvert/SvgSerializer.cpp index 2b24512515..25fbe49198 100644 --- a/src/ifcconvert/SvgSerializer.cpp +++ b/src/ifcconvert/SvgSerializer.cpp @@ -168,7 +168,8 @@ SvgSerializer::path_object& SvgSerializer::start_path(IfcSchema::IfcBuildingStor return p; } -void SvgSerializer::write(const IfcGeom::BRepElement* o) { +void SvgSerializer::write(const IfcGeom::BRepElement* o) +{ IfcSchema::IfcBuildingStorey* storey = 0; IfcSchema::IfcObjectDefinition* obdef = static_cast(file->entityById(o->id())); @@ -340,10 +341,14 @@ void SvgSerializer::writeHeader() { svg_file << "\n"; } -std::string SvgSerializer::nameElement(const IfcGeom::Element* elem) { +std::string SvgSerializer::nameElement(const IfcGeom::Element* elem) +{ std::ostringstream oss; const std::string type = "product"; - oss << "id=\"" << type << "-" << elem->unique_id() << "\""; + const std::string name = (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_GUIDS) + ? elem->guid() : (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_NAMES) + ? elem->name() : elem->unique_id())); + oss << "id=\"" << type << "-" << name<< "\""; return oss.str(); } @@ -352,4 +357,4 @@ std::string SvgSerializer::nameElement(const IfcSchema::IfcProduct* elem) { const std::string type = elem->is(IfcSchema::Type::IfcBuildingStorey) ? "storey" : "product"; oss << "id=\"product-" << IfcParse::IfcGlobalId(elem->GlobalId()).formatted() << "\""; return oss.str(); -} \ No newline at end of file +} diff --git a/src/ifcconvert/SvgSerializer.h b/src/ifcconvert/SvgSerializer.h index 46e44f73bb..ea4acb3aff 100644 --- a/src/ifcconvert/SvgSerializer.h +++ b/src/ifcconvert/SvgSerializer.h @@ -22,15 +22,13 @@ #ifndef SVGSERIALIZER_H #define SVGSERIALIZER_H +#include "../ifcconvert/GeometrySerializer.h" +#include "../ifcconvert/util.h" + #include #include #include -#include "../ifcgeom/IfcGeomIterator.h" - -#include "../ifcconvert/GeometrySerializer.h" -#include "../ifcconvert/util.h" - class SvgSerializer : public GeometrySerializer { public: typedef std::pair > path_object; @@ -45,8 +43,8 @@ protected: std::vector< boost::shared_ptr > radii; IfcParse::IfcFile* file; public: - explicit SvgSerializer(const std::string& out_filename) - : GeometrySerializer() + SvgSerializer(const std::string& out_filename, const IfcGeom::IteratorSettings &settings) + : GeometrySerializer(settings) , svg_file(out_filename.c_str()) , xmin(+std::numeric_limits::infinity()) , xmax(-std::numeric_limits::infinity()) @@ -55,25 +53,24 @@ public: , rescale(false) , file(0) {} - virtual void addXCoordinate(const boost::shared_ptr& fi) { xcoords.push_back(fi); } - virtual void addYCoordinate(const boost::shared_ptr& fi) { ycoords.push_back(fi); } - virtual void addSizeComponent(const boost::shared_ptr& fi) { radii.push_back(fi); } - virtual void growBoundingBox(double x, double y) { if (x < xmin) xmin = x; if (x > xmax) xmax = x; if (y < ymin) ymin = y; if (y > ymax) ymax = y; } - virtual ~SvgSerializer() {} - virtual void writeHeader(); - virtual bool ready(); - virtual void write(const IfcGeom::TriangulationElement* /*o*/) {} - virtual void write(const IfcGeom::BRepElement* o); - virtual void write(path_object& p, const TopoDS_Wire& wire); - virtual path_object& start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id); - virtual bool isTesselated() const { return false; } - virtual void finalize(); - virtual void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {} - virtual void setFile(IfcParse::IfcFile* f) { file = f; } - virtual void setBoundingRectangle(double width, double height); - virtual void setSectionHeight(double h) { section_height = h; } - virtual std::string nameElement(const IfcGeom::Element* elem); - virtual std::string nameElement(const IfcSchema::IfcProduct* elem); + void addXCoordinate(const boost::shared_ptr& fi) { xcoords.push_back(fi); } + void addYCoordinate(const boost::shared_ptr& fi) { ycoords.push_back(fi); } + void addSizeComponent(const boost::shared_ptr& fi) { radii.push_back(fi); } + void growBoundingBox(double x, double y) { if (x < xmin) xmin = x; if (x > xmax) xmax = x; if (y < ymin) ymin = y; if (y > ymax) ymax = y; } + void writeHeader(); + bool ready(); + void write(const IfcGeom::TriangulationElement* /*o*/) {} + void write(const IfcGeom::BRepElement* o); + void write(path_object& p, const TopoDS_Wire& wire); + path_object& start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id); + bool isTesselated() const { return false; } + void finalize(); + void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {} + void setFile(IfcParse::IfcFile* f) { file = f; } + void setBoundingRectangle(double width, double height); + void setSectionHeight(double h) { section_height = h; } + std::string nameElement(const IfcGeom::Element* elem); + std::string nameElement(const IfcSchema::IfcProduct* elem); }; #endif diff --git a/src/ifcconvert/WavefrontObjSerializer.cpp b/src/ifcconvert/WavefrontObjSerializer.cpp index 4bd3f243df..3be2357f39 100644 --- a/src/ifcconvert/WavefrontObjSerializer.cpp +++ b/src/ifcconvert/WavefrontObjSerializer.cpp @@ -17,12 +17,13 @@ * * ********************************************************************************/ -#include -#include + +#include "WavefrontObjSerializer.h" #include "../ifcgeom/IfcGeomRenderStyles.h" -#include "WavefrontObjSerializer.h" +#include +#include bool WaveFrontOBJSerializer::ready() { return obj_stream.is_open() && mtl_stream.is_open(); @@ -41,11 +42,15 @@ void WaveFrontOBJSerializer::writeHeader() { mtl_basename = mtl_basename.substr(slash+1); } obj_stream << "mtllib " << mtl_basename << "\n"; - mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n"; + mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n"; } -void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) { - mtl_stream << "newmtl " << style.name() << "\n"; +void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) +{ + std::string material_name = (settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? style.original_name() : style.name()); + IfcUtil::sanitate_material_name(material_name); + mtl_stream << "newmtl " << material_name << "\n"; if (style.hasDiffuse()) { const double* diffuse = style.diffuse(); mtl_stream << "Kd " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n"; @@ -66,39 +71,50 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) { } } } -void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o) { - obj_stream << "g " << o->unique_id() << "\n"; +void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o) +{ + const std::string name = (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_GUIDS) + ? o->guid() : (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_NAMES) + ? o->name() : o->unique_id())); + obj_stream << "g " << name << "\n"; obj_stream << "s 1" << "\n"; - obj_stream << std::setprecision(std::numeric_limits::digits10); - - const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const int vcount = (int)mesh.verts().size() / 3; - for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { - const double x = *(it++); - const double y = *(it++); - const double z = *(it++); + for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { + const real_t x = *(it++) + (real_t)settings().offset[0]; + const real_t y = *(it++) + (real_t)settings().offset[1]; + const real_t z = *(it++) + (real_t)settings().offset[2]; obj_stream << "v " << x << " " << y << " " << z << "\n"; } - for ( std::vector::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) { - const double x = *(it++); - const double y = *(it++); - const double z = *(it++); + for ( std::vector::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) { + const real_t x = *(it++); + const real_t y = *(it++); + const real_t z = *(it++); obj_stream << "vn " << x << " " << y << " " << z << "\n"; } + for (std::vector::const_iterator it = mesh.uvs().begin(); it != mesh.uvs().end();) { + const real_t u = *it++; + const real_t v = *it++; + obj_stream << "vt " << u << " " << v << "\n"; + } + int previous_material_id = -2; std::vector::const_iterator material_it = mesh.material_ids().begin(); + const bool has_uvs = !mesh.uvs().empty(); 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::Material& material = mesh.materials()[material_id]; - const std::string material_name = material.name(); + std::string material_name = (settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); @@ -110,7 +126,9 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* const int v1 = *(it++)+vcount_total; const int v2 = *(it++)+vcount_total; const int v3 = *(it++)+vcount_total; - obj_stream << "f " << v1 << "//" << v1 << " " << v2 << "//" << v2 << " " << v3 << "//" << v3 << "\n"; + obj_stream << "f " << v1 << "/" << (has_uvs ? boost::lexical_cast(v1) : "") << "/" << v1 << " " + << v2 << "/" << (has_uvs ? boost::lexical_cast(v2) : "") << "/" << v2 << " " + << v3 << "/" << (has_uvs ? boost::lexical_cast(v3) : "") << "/" << v3 << "\n"; } @@ -129,7 +147,9 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* if (material_id != previous_material_id) { const IfcGeom::Material& material = mesh.materials()[material_id]; - const std::string material_name = material.name(); + std::string material_name = (settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) + ? material.original_name() : material.name()); + IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); diff --git a/src/ifcconvert/WavefrontObjSerializer.h b/src/ifcconvert/WavefrontObjSerializer.h index 1b1ae7d69d..52117c62a3 100644 --- a/src/ifcconvert/WavefrontObjSerializer.h +++ b/src/ifcconvert/WavefrontObjSerializer.h @@ -26,6 +26,7 @@ #include "../ifcconvert/GeometrySerializer.h" +// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt class WaveFrontOBJSerializer : public GeometrySerializer { private: const std::string mtl_filename; @@ -34,8 +35,8 @@ private: unsigned int vcount_total; std::set materials; public: - WaveFrontOBJSerializer(const std::string& obj_filename, const std::string& mtl_filename) - : GeometrySerializer() + WaveFrontOBJSerializer(const std::string& obj_filename, const std::string& mtl_filename, const IfcGeom::IteratorSettings &settings) + : GeometrySerializer(settings) , obj_stream(obj_filename.c_str()) , mtl_filename(mtl_filename) , mtl_stream(mtl_filename.c_str()) @@ -45,12 +46,12 @@ public: bool ready(); void writeHeader(); void writeMaterial(const IfcGeom::Material& style); - void write(const IfcGeom::TriangulationElement* o); - void write(const IfcGeom::BRepElement* /*o*/) {} + void write(const IfcGeom::TriangulationElement* o); + void write(const IfcGeom::BRepElement* /*o*/) {} void finalize() {} bool isTesselated() const { return true; } void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {} void setFile(IfcParse::IfcFile*) {} }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index 9a8cc05d95..fbec20e6c8 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include "XmlSerializer.h" @@ -164,6 +163,16 @@ void descend(IfcProduct* product, ptree& tree) { } } + if (product->is(Type::IfcElement)) { + IfcElement* element = static_cast(product); + IfcOpeningElement::list::ptr openings = get_related( + element, &IfcElement::HasOpenings, &IfcRelVoidsElement::RelatedOpeningElement); + + for (IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) { + descend(*it, child); + } + } + #ifdef USE_IFC2x3 IfcObjectDefinition::list::ptr structures = get_related @@ -246,16 +255,16 @@ void XmlSerializer::finalize() { ptree root, header, decomposition, properties; // Write the SPF header as XML nodes. - BOOST_FOREACH(const std::string& s, file->header().file_description().description()) { + foreach(const std::string& s, file->header().file_description().description()) { header.add_child("file_description.description", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_name().author()) { + foreach(const std::string& s, file->header().file_name().author()) { header.add_child("file_name.author", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_name().organization()) { + foreach(const std::string& s, file->header().file_name().organization()) { header.add_child("file_name.organization", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_schema().schema_identifiers()) { + foreach(const std::string& s, file->header().file_schema().schema_identifiers()) { header.add_child("file_schema.schema_identifiers", ptree(s)); } header.put("file_description.implementation_level", file->header().file_description().implementation_level()); @@ -288,4 +297,4 @@ void XmlSerializer::finalize() { boost::property_tree::xml_writer_settings settings('\t', 1); #endif boost::property_tree::write_xml(xml_filename, root, std::locale(), settings); -} \ No newline at end of file +} diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index e69ea09e9f..b363c38e1a 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -44,7 +44,7 @@ namespace IfcGeom { for(int i = 1; i < 5; ++i) { for (int j = 1; j < 4; ++j) { const double trsf_value = trsf.Value(j,i); - const double matrix_value = i == 4 && settings.convert_back_units() + const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS) ? trsf_value / settings.unit_magnitude() : trsf_value; _data.push_back(static_cast

(matrix_value)); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index d2c8a21d7f..4b1df71645 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1116,11 +1116,11 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro const std::string product_type = IfcSchema::Type::ToString(product->type()); ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type); - if ( !settings.disable_opening_subtractions() && openings && openings->size() ) { + if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) { IfcGeom::IfcRepresentationShapeItems opened_shapes; try { #if OCC_VERSION_HEX < 0x60900 - const bool faster_booleans = settings.faster_booleans(); + const bool faster_booleans = settings.get(IteratorSettings::FASTER_BOOLEANS); #else const bool faster_booleans = true; #endif @@ -1136,14 +1136,14 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro } catch(...) { Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product->entity); } - if ( settings.use_world_coords() ) { + if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) { it->prepend(trsf); } trsf = gp_Trsf(); } shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), opened_shapes); - } else if ( settings.use_world_coords() ) { + } else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) { it->prepend(trsf); } diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 7e294f260a..cf07d9e603 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -86,6 +86,9 @@ namespace IfcGeom { template class Iterator { private: + Iterator(const Iterator&); // N/I + Iterator& operator=(const Iterator&); // N/I + Kernel kernel; IteratorSettings settings; @@ -110,6 +113,8 @@ namespace IfcGeom { std::string unit_name; // double? P unit_magnitude; + gp_XYZ bounds_min_; + gp_XYZ bounds_max_; void initUnits() { IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType(); @@ -121,6 +126,7 @@ namespace IfcGeom { } } + std::set names_to_include_or_exclude; // regex containing a name or a wildcard expression std::set entities_to_include_or_exclude; bool include_entities_in_processing; @@ -148,7 +154,7 @@ namespace IfcGeom { } catch (...) {} std::set context_types; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { // Really this should only be 'Model', as per // the standard 'Design' is deprecated. So, // just for backwards compatibility: @@ -157,7 +163,7 @@ namespace IfcGeom { // DDS likes to output 'model view' context_types.insert("model view"); } - if (settings.include_curves()) { + if (settings.get(IteratorSettings::INCLUDE_CURVES)) { context_types.insert("plan"); } @@ -247,39 +253,74 @@ namespace IfcGeom { done = 0; total = representations->size(); + for (int i = 1; i < 4; ++i) { + bounds_min_.SetCoord(i, std::numeric_limits::infinity()); + bounds_max_.SetCoord(i, -std::numeric_limits::infinity()); + } + + IfcSchema::IfcProduct::list::ptr products = ifc_file->entitiesByType(); + for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) { + IfcSchema::IfcProduct* product = *iter; + if (product->hasObjectPlacement()) { + gp_Trsf trsf; // Use a fresh trsf every time in order to prevent the result to be concatenated + if (kernel.convert(product->ObjectPlacement(), trsf)) { + const gp_XYZ& pos = trsf.TranslationPart(); + bounds_min_.SetX(std::min(bounds_min_.X(), pos.X())); + bounds_min_.SetY(std::min(bounds_min_.Y(), pos.Y())); + bounds_min_.SetZ(std::min(bounds_min_.Z(), pos.Z())); + bounds_max_.SetX(std::max(bounds_max_.X(), pos.X())); + bounds_max_.SetY(std::max(bounds_max_.Y(), pos.Y())); + bounds_max_.SetZ(std::max(bounds_max_.Z(), pos.Z())); + } + } + } + return true; } - int progress() { - return 100 * done / total; - } + int progress() const { return 100 * done / total; } - const std::string& getUnitName() { - return unit_name; - } + const std::string& getUnitName() const { return unit_name; } - const P getUnitMagnitude() { - return unit_magnitude; - } + P getUnitMagnitude() const { return unit_magnitude; } - const std::string getLog() { - return Logger::GetLog(); - } + std::string getLog() const { return Logger::GetLog(); } - IfcParse::IfcFile* getFile() { - return ifc_file; - } + IfcParse::IfcFile* getFile() const { return ifc_file; } + /// @note Entity names are handled case-insensitively. void includeEntities(const std::set& entities) { populate_set(entities); include_entities_in_processing = true; } + /// @note Entity names are handled case-insensitively. void excludeEntities(const std::set& entities) { populate_set(entities); include_entities_in_processing = false; } + /// @note Arbitrary names or wildcard expressions are handled case-sensitively. + void include_entity_names(const std::vector& names) + { + names_to_include_or_exclude.clear(); + foreach(const std::string &name, names) + names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name)); + include_entities_in_processing = true; + } + + /// @note Arbitrary names or wildcard expressions are handled case-sensitively. + void exclude_entity_names(const std::vector& names) + { + names_to_include_or_exclude.clear(); + foreach(const std::string &name, names) + names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name)); + include_entities_in_processing = false; + } + + const gp_XYZ& bounds_min() const { return bounds_min_; } + const gp_XYZ& bounds_max() const { return bounds_max_; } + private: // Move to the next IfcRepresentation void _nextShape() { @@ -340,7 +381,7 @@ namespace IfcGeom { } } - const bool process_maps_for_current_representation = (!has_openings || settings.disable_opening_subtractions()); + const bool process_maps_for_current_representation = (!has_openings || settings.get(IteratorSettings::DISABLE_OPENING_SUBTRACTIONS)); bool representation_processed_as_mapped_item = false; IfcSchema::IfcRepresentation* representation_mapped_to = 0; @@ -365,7 +406,7 @@ namespace IfcGeom { IfcSchema::IfcProduct::list::ptr products_of_prodrep = (*it)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as(); products->push(products_of_prodrep); for (IfcSchema::IfcProduct::list::it jt = products_of_prodrep->begin(); jt != products_of_prodrep->end(); ++jt) { - if (kernel.find_openings(*jt)->size() > 0 && !settings.disable_opening_subtractions()) { + if (kernel.find_openings(*jt)->size() > 0 && !settings.get(IteratorSettings::DISABLE_OPENING_SUBTRACTIONS)) { all_product_without_openings = false; break; } @@ -418,7 +459,7 @@ namespace IfcGeom { for (IfcSchema::IfcProductRepresentation::list::it kt = prodreps->begin(); kt != prodreps->end(); ++kt) { IfcSchema::IfcProduct::list::ptr prods = (*kt)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as(); for (IfcSchema::IfcProduct::list::it lt = prods->begin(); lt != prods->end(); ++lt) { - if (kernel.find_openings(*lt)->size() == 0 || settings.disable_opening_subtractions()) { + if (kernel.find_openings(*lt)->size() == 0 || settings.get(IteratorSettings::DISABLE_OPENING_SUBTRACTIONS)) { if (!unfiltered_products->contains(*lt)) { unfiltered_products->push(*lt); } @@ -440,6 +481,14 @@ namespace IfcGeom { break; } } + + foreach(const boost::regex& r, names_to_include_or_exclude) { + if (boost::regex_match((*jt)->Name(), r)) { + found = true; + break; + } + } + if (found == include_entities_in_processing) { ifcproducts->push(*jt); } @@ -494,13 +543,17 @@ namespace IfcGeom { return create(); } - Element

* get() { - // TODO: Test settings and throw - if (current_triangulation) return current_triangulation; - else if (current_serialization) return current_serialization; - else if (current_shape_model) return current_shape_model; - else return 0; - } + /// Gets or takes the representation of the current geometrical entity. + /// @param take_ownership Pass in 'true' as if wishing to maintain the element lifetime yourself. + Element

* get(bool take_ownership = false) + { + // TODO: Test settings and throw + Element

* ret = 0; + if (current_triangulation) { ret = current_triangulation; if (take_ownership) current_triangulation = 0; } + else if (current_serialization) { ret = current_serialization; if (take_ownership) current_serialization = 0; } + else if (current_shape_model) { ret = current_shape_model; if (take_ownership) current_shape_model = 0; } + return ret; + } const Element

* getObject(int id) { @@ -549,15 +602,15 @@ namespace IfcGeom { } catch (...) {} if (next_shape_model) { - if (settings.use_brep_data()) { + if (settings.get(IteratorSettings::USE_BREP_DATA)) { try { next_serialization = new SerializedElement

(*next_shape_model); } catch (...) { success = false; } - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) { try { - if (ifcproduct_iterator == ifcproducts->begin() || settings.use_world_coords()) { + if (ifcproduct_iterator == ifcproducts->begin() || settings.get(IteratorSettings::USE_WORLD_COORDS)) { next_triangulation = new TriangulationElement

(*next_shape_model); } else { next_triangulation = new TriangulationElement

(*next_shape_model, current_triangulation->geometry_pointer()); @@ -591,8 +644,9 @@ namespace IfcGeom { unit_name = "METER"; unit_magnitude = 1.f; - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1); - kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.)); + kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1); + kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) + ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); } bool owns_ifc_file; diff --git a/src/ifcgeom/IfcGeomIteratorSettings.h b/src/ifcgeom/IfcGeomIteratorSettings.h index 7adc5e9463..bf225ef3c9 100644 --- a/src/ifcgeom/IfcGeomIteratorSettings.h +++ b/src/ifcgeom/IfcGeomIteratorSettings.h @@ -20,160 +20,145 @@ #ifndef IFCGEOMITERATORSETTINGS_H #define IFCGEOMITERATORSETTINGS_H -#include - #include "../ifcparse/IfcException.h" +#include "../ifcparse/IfcUtil.h" -namespace IfcGeom { +namespace IfcGeom +{ + class IteratorSettings + { + public: + /// Enumeration of setting identifiers. These settings define the + /// behaviour of various aspects of IfcOpenShell. + enum Setting + { + /// Specifies whether vertices are welded, meaning that the coordinates + /// vector will only contain unique xyz-triplets. This results in a + /// manifold mesh which is useful for modelling applications, but might + /// result in unwanted shading artifacts in rendering applications. + WELD_VERTICES = 1, + /// Specifies whether to apply the local placements of building elements + /// directly to the coordinates of the representation mesh rather than + /// to represent the local placement in the 4x3 matrix, which will in that + /// case be the identity matrix. + USE_WORLD_COORDS = 1 << 1, + /// Internally IfcOpenShell measures everything in meters. This settings + /// specifies whether to convert IfcGeomObjects back to the units in which + /// the geometry in the IFC file is specified. + CONVERT_BACK_UNITS = 1 << 2, + /// Specifies whether to use the Open Cascade BREP format for representation + /// items rather than to create triangle meshes. This is useful is IfcOpenShell + /// is used as a library in an application that is also built on Open Cascade. + USE_BREP_DATA = 1 << 3, + /// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to + /// TopoDS_Shells or whether to keep them as a loose collection of faces. + SEW_SHELLS = 1 << 4, + /// Specifies whether to compose IfcOpeningElements into a single compound + /// in order to speed up the processing of opening subtractions. + FASTER_BOOLEANS = 1 << 5, + /// Disables the subtraction of IfcOpeningElement representations from + /// the related building element representations. + DISABLE_OPENING_SUBTRACTIONS = 1 << 6, + /// Disables the triangulation of the topological representations. Useful if + /// the client application understands Open Cascade's native format. + DISABLE_TRIANGULATION = 1 << 7, + /// Applies default materials to entity instances without a surface style. + APPLY_DEFAULT_MATERIALS = 1 << 8, + /// Specifies whether to include subtypes of IfcCurve. + INCLUDE_CURVES = 1 << 9, + /// Specifies whether to exclude subtypes of IfcSolidModel and IfcSurface. + EXCLUDE_SOLIDS_AND_SURFACES = 1 << 10, + /// Disables computation of normals. Saves time and file size and is useful + /// in instances where you're going to recompute normals for the exported + /// model in other modelling application in any case. + NO_NORMALS = 1 << 11, + /// Use entity names instead of unique IDs for naming elements. + /// Applicable for OBJ, DAE, and SVG output. + USE_ELEMENT_NAMES = 1 << 12, + /// Use entity GUIDs instead of unique IDs for naming elements. + /// Applicable for OBJ, DAE, and SVG output. + USE_ELEMENT_GUIDS = 1 << 13, + /// Use material names instead of unique IDs for naming materials. + /// Applicable for OBJ and DAE output. + USE_MATERIAL_NAMES = 1 << 14, + /// Centers the models upon serialization by the applying the center point of + /// the scene bounds as an offset. Applicable only for DAE output currently. + CENTER_MODEL = 1 << 15, + /// Generates UVs by using simple box projection. Requires normals. + /// Applicable only for DAE output currently. + GENERATE_UVS = 1 << 16, + /// Number of different setting flags. + NUM_SETTINGS = 16 + }; + /// Used to store logical OR combination of setting flags. + typedef unsigned SettingField; - class IteratorSettings { - public: - // Enumeration of setting identifiers. These settings define the - // behaviour of various aspects of IfcOpenShell. + IteratorSettings() + : settings_(WELD_VERTICES) // OR options that default to true here + , deflection_tolerance_(1.e-3) + { + memset(offset, 0, sizeof(offset)); + } - // Specifies whether vertices are welded, meaning that the coordinates - // vector will only contain unique xyz-triplets. This results in a - // manifold mesh which is useful for modelling applications, but might - // result in unwanted shading artifacts in rendering applications. - static const int WELD_VERTICES = 1; - // Specifies whether to apply the local placements of building elements - // directly to the coordinates of the representation mesh rather than - // to represent the local placement in the 4x3 matrix, which will in that - // case be the identity matrix. - static const int USE_WORLD_COORDS = 2; - // Internally IfcOpenShell measures everything in meters. This settings - // specifies whether to convert IfcGeomObjects back to the units in which - // the geometry in the IFC file is specified. - static const int CONVERT_BACK_UNITS = 3; - // Specifies whether to use the Open Cascade BREP format for representation - // items rather than to create triangle meshes. This is useful is IfcOpenShell - // is used as a library in an application that is also built on Open Cascade. - static const int USE_BREP_DATA = 4; - // Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to - // TopoDS_Shells or whether to keep them as a loose collection of faces. - static const int SEW_SHELLS = 5; - // Specifies whether to compose IfcOpeningElements into a single compound - // in order to speed up the processing of opening subtractions. - static const int FASTER_BOOLEANS = 6; - // Disables the subtraction of IfcOpeningElement representations from - // the related building element representations. - static const int DISABLE_OPENING_SUBTRACTIONS = 8; - // Disables the triangulation of the topological representations. Useful if - // the client application understands Open Cascade's native format. - static const int DISABLE_TRIANGULATION = 9; - // Applies default materials to entity instances without a surface style. - static const int APPLY_DEFAULT_MATERIALS = 10; - // Specifies whether to include subtypes of IfcCurve. - static const int INCLUDE_CURVES = 11; - // Specifies whether to exclude subtypes of IfcSolidModel and IfcSurface. - static const int EXCLUDE_SOLIDS_AND_SURFACES = 12; + /// Optional offset that is applied to serialized objects, (0,0,0) by default. + double offset[3]; - // End of settings enumeration. + /// Note that this is independent of the IFC length unit, one millimeter by default. + double deflection_tolerance() const { return deflection_tolerance_; } - private: - bool _weld_vertices, _use_world_coords, _convert_back_units, _use_brep_data, _sew_shells, _faster_booleans, _disable_opening_subtractions, _disable_triangulation, _apply_default_materials, _include_curves, _exclude_solids_and_surfaces; - double _deflection_tolerance; - public: - IteratorSettings() - : _weld_vertices(true) - , _use_world_coords(false) - , _convert_back_units(false) - , _use_brep_data(false) - , _sew_shells(false) - , _faster_booleans(false) - , _disable_opening_subtractions(false) - , _disable_triangulation(false) - , _apply_default_materials(false) - , _include_curves(false) - , _exclude_solids_and_surfaces(false) - // TODO: Make deflection tolerance into a command line argument - // For now, stick to one millimeter. Note that this is independent of the IFC length unit. - , _deflection_tolerance(1.e-3) - {} + void set_deflection_tolerance(double value) + { + /// @todo Using deflection tolerance of 1e-6 or smaller hangs the conversion, research more in-depth. + /// This bug can be reproduced e.g. with the Duplex model that can be found from http://www.nibs.org/?page=bsa_commonbimfiles#project1 + deflection_tolerance_ = value; + if (deflection_tolerance_ <= 1e-6) { + Logger::Message(Logger::LOG_WARNING, "Deflection tolerance cannot be set to <= 1e-6; using the default value 1e-3"); + deflection_tolerance_ = 1e-3; + } + } - const bool& weld_vertices() const { return _weld_vertices; } - bool& weld_vertices() { return _weld_vertices; } - const bool& use_world_coords() const { return _use_world_coords; } - bool& use_world_coords() { return _use_world_coords; } - const bool& convert_back_units() const { return _convert_back_units; } - bool& convert_back_units() { return _convert_back_units; } - const bool& use_brep_data() const { return _use_brep_data; } - bool& use_brep_data() { return _use_brep_data; } - const bool& sew_shells() const { return _sew_shells; } - bool& sew_shells() { return _sew_shells; } - const bool& faster_booleans() const { return _faster_booleans; } - bool& faster_booleans() { return _faster_booleans; } - const bool& disable_opening_subtractions() const { return _disable_opening_subtractions; } - bool& disable_opening_subtractions() { return _disable_opening_subtractions; } - const bool& disable_triangulation() const { return _disable_triangulation; } - bool& disable_triangulation() { return _disable_triangulation; } - const bool& apply_default_materials() const { return _apply_default_materials; } - bool& apply_default_materials() { return _apply_default_materials; } - const bool& include_curves() const { return _include_curves; } - bool& include_curves() { return _include_curves; } - const bool& exclude_solids_and_surfaces() const { return _exclude_solids_and_surfaces; } - bool& exclude_solids_and_surfaces() { return _exclude_solids_and_surfaces; } - - const double& deflection_tolerance() const { return _deflection_tolerance; } - double& deflection_tolerance() { return _deflection_tolerance; } - - void set(int setting, bool value) { - switch (setting) { - case USE_WORLD_COORDS: - _use_world_coords = value; - break; - case WELD_VERTICES: - _weld_vertices = value; - break; - case CONVERT_BACK_UNITS: - _convert_back_units = value; - break; - case USE_BREP_DATA: - _use_brep_data = value; - break; - case FASTER_BOOLEANS: - _faster_booleans = value; - break; - case SEW_SHELLS: - _sew_shells = value; - break; - case DISABLE_OPENING_SUBTRACTIONS: - _disable_opening_subtractions = value; - break; - case DISABLE_TRIANGULATION: - _disable_triangulation = value; - break; - case APPLY_DEFAULT_MATERIALS: - _apply_default_materials = value; - break; - case INCLUDE_CURVES: - _include_curves = value; - break; - case EXCLUDE_SOLIDS_AND_SURFACES: - _exclude_solids_and_surfaces = value; - break; - default: throw IfcParse::IfcException("Invalid IteratorSetting"); - } - } - }; - - class ElementSettings : public IteratorSettings { - private: - double _unit_magnitude; - std::string _element_type; - public: - ElementSettings(const IteratorSettings& settings, - double unit_magnitude, - const std::string& element_type) - : IteratorSettings(settings) - , _unit_magnitude(unit_magnitude) - , _element_type(element_type) - {} + /// Get boolean value for a single settings or for a combination of settings. + bool get(SettingField setting) const + { + /// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")? + return (settings_ & setting) != 0; + } - const double& unit_magnitude() const { return _unit_magnitude; } - const std::string& element_type() const { return _element_type; } - }; + /// Set boolean value for a single settings or for a combination of settings. + void set(SettingField setting, bool value) + { + /// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")? + if (value) { + settings_ |= setting; + } else { + settings_ &= ~setting; + } + } + protected: + SettingField settings_; + double deflection_tolerance_; + }; + + class ElementSettings : public IteratorSettings + { + public: + ElementSettings(const IteratorSettings& settings, + double unit_magnitude, + const std::string& element_type) + : IteratorSettings(settings) + , unit_magnitude_(unit_magnitude) + , element_type_(element_type) + { + } + + double unit_magnitude() const { return unit_magnitude_; } + const std::string& element_type() const { return element_type_; } + + private: + double unit_magnitude_; + std::string element_type_; + }; } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/IfcGeomMaterial.cpp b/src/ifcgeom/IfcGeomMaterial.cpp index b96eeebcc6..3593ed7673 100644 --- a/src/ifcgeom/IfcGeomMaterial.cpp +++ b/src/ifcgeom/IfcGeomMaterial.cpp @@ -30,5 +30,6 @@ const double* IfcGeom::Material::diffuse() const { if (hasDiffuse()) return &((* const double* IfcGeom::Material::specular() const { if (hasSpecular()) return &((*style->Specular()).R()); else return black; } double IfcGeom::Material::transparency() const { if (hasTransparency()) return *style->Transparency(); else return 0; } double IfcGeom::Material::specularity() const { if (hasSpecularity()) return *style->Specularity(); else return 0; } -const std::string IfcGeom::Material::name() const { return style->Name(); } +const std::string &IfcGeom::Material::name() const { return style->Name(); } +const std::string &IfcGeom::Material::original_name() const { return style->original_name(); } bool IfcGeom::Material::operator==(const IfcGeom::Material& other) const { return style == other.style; } diff --git a/src/ifcgeom/IfcGeomMaterial.h b/src/ifcgeom/IfcGeomMaterial.h index 43228c2d00..9dc4dd7995 100644 --- a/src/ifcgeom/IfcGeomMaterial.h +++ b/src/ifcgeom/IfcGeomMaterial.h @@ -41,10 +41,11 @@ namespace IfcGeom { const double* specular() const; double transparency() const; double specularity() const; - const std::string name() const; + const std::string &name() const; + const std::string &original_name() const; bool operator==(const Material& other) const; }; } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/IfcGeomRenderStyles.h b/src/ifcgeom/IfcGeomRenderStyles.h index a970f15a4e..4c97b06406 100644 --- a/src/ifcgeom/IfcGeomRenderStyles.h +++ b/src/ifcgeom/IfcGeomRenderStyles.h @@ -45,21 +45,21 @@ namespace IfcGeom { }; private: std::string name; + std::string original_name_; boost::optional id; boost::optional diffuse, specular; boost::optional transparency; boost::optional specularity; public: - SurfaceStyle() { - this->name = "surface-style"; - } + SurfaceStyle() : name("surface-style") {} SurfaceStyle(int id) : id(id) { std::stringstream sstr; sstr << "surface-style-" << id; this->name = sstr.str(); } - SurfaceStyle(const std::string& name) : name(name) {} - SurfaceStyle(int id, const std::string& name) : id(id) { + SurfaceStyle(const std::string& name) : name(name), original_name_(name) {} + SurfaceStyle(int id, const std::string& name) : id(id), original_name_(name) + { std::stringstream sstr; std::string sanitized = name; std::transform(sanitized.begin(), sanitized.end(), sanitized.begin(), ::tolower); @@ -76,8 +76,12 @@ namespace IfcGeom { return name == other.name; } + /// ID name, e.g. "surface-style-66675-metal---aluminium" const std::string& Name() const { return name; } + /// Original name, if available, e.g. "Metal - Aluminium" + const std::string& original_name() const { return original_name_; } + const boost::optional& Diffuse() const { return diffuse; } const boost::optional& Specular() const { return specular; } const boost::optional& Transparency() const { return transparency; } @@ -91,4 +95,4 @@ namespace IfcGeom { const SurfaceStyle* get_default_style(const std::string& ifc_type); } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/IfcGeomRepresentation.cpp b/src/ifcgeom/IfcGeomRepresentation.cpp index 15801265ae..abd17a15d9 100644 --- a/src/ifcgeom/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/IfcGeomRepresentation.cpp @@ -38,7 +38,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep) for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it) { const TopoDS_Shape& s = it->Shape(); gp_GTrsf trsf = it->Placement(); - if (settings().convert_back_units()) { + if (settings().get(IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); diff --git a/src/ifcgeom/IfcGeomRepresentation.h b/src/ifcgeom/IfcGeomRepresentation.h index 7b5f635a33..95e41ccaa6 100644 --- a/src/ifcgeom/IfcGeomRepresentation.h +++ b/src/ifcgeom/IfcGeomRepresentation.h @@ -103,6 +103,7 @@ namespace IfcGeom { std::vector _faces; std::vector _edges; std::vector

_normals; + std::vector

uvs_; std::vector _material_ids; std::vector _materials; VertexKeyMap welds; @@ -113,8 +114,10 @@ namespace IfcGeom { const std::vector& faces() const { return _faces; } const std::vector& edges() const { return _edges; } const std::vector

& normals() const { return _normals; } + const std::vector

& uvs() const { return uvs_; } const std::vector& material_ids() const { return _material_ids; } const std::vector& materials() const { return _materials; } + Triangulation(const BRep& shape_model) : Representation(shape_model.settings()) , _id(shape_model.getId()) @@ -133,7 +136,7 @@ namespace IfcGeom { } } - if (settings().apply_default_materials() && surface_style_id == -1) { + if (settings().get(IteratorSettings::APPLY_DEFAULT_MATERIALS) && surface_style_id == -1) { Material material(IfcGeom::get_default_style(settings().element_type())); std::vector::const_iterator mit = std::find(_materials.begin(), _materials.end(), material); if (mit == _materials.end()) { @@ -182,8 +185,9 @@ namespace IfcGeom { BRepGProp_Face prop(face); std::map dict; - // Vertex normals are only calculated if vertices are not welded - const bool calculate_normals = !settings().weld_vertices(); + // Vertex normals are only calculated if vertices are not welded and calculation is not disable explicitly. + const bool calculate_normals = !settings().get(IteratorSettings::WELD_VERTICES) && + !settings().get(IteratorSettings::NO_NORMALS); for( int i = 1; i <= nodes.Length(); ++ i ) { coords.push_back(nodes(i).Transformed(loc).XYZ()); @@ -246,6 +250,10 @@ namespace IfcGeom { } } + if (!_normals.empty() && settings().get(IfcGeom::IteratorSettings::GENERATE_UVS)) { + uvs_ = box_project_uvs(_verts, _normals); + } + if (num_faces == 0) { // Edges are only emitted if there are no faces. A mixed representation of faces // and loose edges is discouraged by the standard. An alternative would be to use @@ -277,14 +285,46 @@ namespace IfcGeom { } } virtual ~Triangulation() {} + + /// Generates UVs for a single mesh using box projection. + /// @todo Very simple impl. Assumes that input vertices and normals match 1:1. + static std::vector

box_project_uvs(const std::vector

&vertices, const std::vector

&normals) + { + std::vector

uvs; + uvs.resize(vertices.size() / 3 * 2); + for (size_t uv_idx = 0, v_idx = 0; + uv_idx < uvs.size() && v_idx < vertices.size() && v_idx < normals.size(); + uv_idx += 2, v_idx += 3) { + + P n_x = normals[v_idx], n_y = normals[v_idx + 1], n_z = normals[v_idx + 2]; + P v_x = vertices[v_idx], v_y = vertices[v_idx + 1], v_z = vertices[v_idx + 2]; + + if (std::abs(n_x) > std::abs(n_y) && std::abs(n_x) > std::abs(n_z)) { + uvs[uv_idx] = v_z; + uvs[uv_idx + 1] = v_y; + } + if (std::abs(n_y) > std::abs(n_x) && std::abs(n_y) > std::abs(n_z)) { + uvs[uv_idx] = v_x; + uvs[uv_idx + 1] = v_z; + } + if (std::abs(n_z) > std::abs(n_x) && std::abs(n_z) > std::abs(n_y)) { + uvs[uv_idx] = v_x; + uvs[uv_idx + 1] = v_y; + } + } + + return uvs; + } + private: // Welds vertices that belong to different faces int addVertex(int material_index, const gp_XYZ& p) { - const P X = static_cast

(settings().convert_back_units() ? (p.X() / settings().unit_magnitude()) : p.X()); - const P Y = static_cast

(settings().convert_back_units() ? (p.Y() / settings().unit_magnitude()) : p.Y()); - const P Z = static_cast

(settings().convert_back_units() ? (p.Z() / settings().unit_magnitude()) : p.Z()); + const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS); + const P X = static_cast

(convert ? (p.X() / settings().unit_magnitude()) : p.X()); + const P Y = static_cast

(convert ? (p.Y() / settings().unit_magnitude()) : p.Y()); + const P Z = static_cast

(convert ? (p.Z() / settings().unit_magnitude()) : p.Z()); int i = (int) _verts.size() / 3; - if (settings().weld_vertices()) { + if (settings().get(IteratorSettings::WELD_VERTICES)) { const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z))); typename VertexKeyMap::const_iterator it = welds.find(key); if ( it != welds.end() ) return it->second; @@ -310,4 +350,4 @@ namespace IfcGeom { } } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index 975c3c471e..0b37b739aa 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -318,10 +318,10 @@ int main () { memcpy(data, m.string().c_str(), len); IfcGeom::IteratorSettings settings; - settings.use_world_coords() = false; - settings.weld_vertices() = false; - settings.convert_back_units() = true; - settings.include_curves() = true; + settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); + settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false); + settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true); + settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, true); iterator = new IfcGeom::Iterator(settings, data, (int)len); has_more = iterator->initialize(); diff --git a/src/ifcmax/IfcMax.cpp b/src/ifcmax/IfcMax.cpp index 46bf0f39f8..28ab422882 100644 --- a/src/ifcmax/IfcMax.cpp +++ b/src/ifcmax/IfcMax.cpp @@ -214,9 +214,9 @@ static Mtl* ComposeMultiMaterial(std::map, Mtl*>& multi int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL /*suppressPrompts*/) { IfcGeom::IteratorSettings settings; - settings.use_world_coords() = false; - settings.weld_vertices() = true; - settings.sew_shells() = true; + settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); + settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, true); + settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true); #ifdef _UNICODE int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0); diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index bd98473a1d..9b23760c75 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -69,7 +69,10 @@ void init_locale() { // // Opens the file, gets the filesize and reads a chunk in memory // -IfcSpfStream::IfcSpfStream(const std::string& fn) { +IfcSpfStream::IfcSpfStream(const std::string& fn) + : stream(0) + , buffer(0) +{ eof = false; #ifdef _MSC_VER int fn_buffer_size = MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, 0, 0); @@ -86,7 +89,7 @@ IfcSpfStream::IfcSpfStream(const std::string& fn) { } valid = true; fseek(stream, 0, SEEK_END); - size = (unsigned int) ftell(stream);; + size = (unsigned int) ftell(stream); rewind(stream); #ifdef BUF_SIZE offset = 0; @@ -96,11 +99,14 @@ IfcSpfStream::IfcSpfStream(const std::string& fn) { buffer = new char[size]; #endif ptr = 0; - len = 0; + len = 0; ReadBuffer(false); } -IfcSpfStream::IfcSpfStream(std::istream& f, int l) { +IfcSpfStream::IfcSpfStream(std::istream& f, int l) + : stream(0) + , buffer(0) +{ eof = false; size = l; #ifdef BUF_SIZE @@ -114,7 +120,10 @@ IfcSpfStream::IfcSpfStream(std::istream& f, int l) { len = l; } -IfcSpfStream::IfcSpfStream(void* data, int l) { +IfcSpfStream::IfcSpfStream(void* data, int l) + : stream(0) + , buffer(0) +{ eof = false; size = l; #ifdef BUF_SIZE @@ -124,7 +133,7 @@ IfcSpfStream::IfcSpfStream(void* data, int l) { buffer = (char*) data; valid = true; ptr = 0; - len = l; + len = l; } IfcSpfStream::~IfcSpfStream() diff --git a/src/ifcparse/IfcUtil.cpp b/src/ifcparse/IfcUtil.cpp index 0f4bc13734..80bd257b14 100644 --- a/src/ifcparse/IfcUtil.cpp +++ b/src/ifcparse/IfcUtil.cpp @@ -17,12 +17,14 @@ * * ********************************************************************************/ +#include "IfcUtil.h" +#include "../ifcparse/IfcException.h" + +#include + #include #include -#include "../ifcparse/IfcException.h" - -#include "IfcUtil.h" void IfcEntityList::push(IfcUtil::IfcBaseClass* l) { if (l) { @@ -143,4 +145,43 @@ bool IfcUtil::valid_binary_string(const std::string& s) { if (*it != '0' && *it != '1') return false; } return true; -} \ No newline at end of file +} + +boost::regex IfcUtil::wildcard_string_to_regex(std::string str) +{ + // Escape all non-"*?" regex special chars + std::string special_chars = "\\^.$|()[]+/"; + foreach(char c, special_chars) { + std::string char_str(1, c); + boost::replace_all(str, char_str, "\\"+ char_str); + } + // Convert "*?" to their regex equivalents + boost::replace_all(str, "?", "."); + boost::replace_all(str, "*", ".*"); + return boost::regex(str); +} + +void IfcUtil::sanitate_material_name(std::string &str) +{ + // Spaces in material names have been observed to cause problems with obj and dae importers. + // Handle other potential problematic characters here too if observing problems. + boost::replace_all(str, " ", "_"); +} + +void IfcUtil::escape_xml(std::string &str) +{ + boost::replace_all(str, "\"", """); + boost::replace_all(str, "'", "'"); + boost::replace_all(str, "<", "<"); + boost::replace_all(str, ">", ">"); + boost::replace_all(str, "&", "&"); +} + +void IfcUtil::unescape_xml(std::string &str) +{ + boost::replace_all(str, """, "\""); + boost::replace_all(str, "'", "'"); + boost::replace_all(str, "<", "<"); + boost::replace_all(str, ">", ">"); + boost::replace_all(str, "&", "&"); +} diff --git a/src/ifcparse/IfcUtil.h b/src/ifcparse/IfcUtil.h index 19ffead06c..5e51d8232a 100644 --- a/src/ifcparse/IfcUtil.h +++ b/src/ifcparse/IfcUtil.h @@ -26,15 +26,20 @@ #include #include -#include -#include - #ifdef USE_IFC4 #include "../ifcparse/Ifc4enum.h" #else #include "../ifcparse/Ifc2x3enum.h" #endif +#include +#include +#include +#include + +#define foreach BOOST_FOREACH +#define rforeach BOOST_REVERSE_FOREACH + class Argument; class IfcEntityList; class IfcEntityListList; @@ -110,6 +115,13 @@ namespace IfcUtil { }; bool valid_binary_string(const std::string& s); + + boost::regex wildcard_string_to_regex(std::string str); + + /// Replaces spaces and potentially other problem causing characters with underscores. + void sanitate_material_name(std::string &str); + void escape_xml(std::string &str); + void unescape_xml(std::string &str); } template diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 84a435b69e..e0db875565 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -244,8 +244,8 @@ struct ShapeRTTI : public boost::static_visitor IfcSchema::IfcProject* project = *projects->begin(); IfcGeom::Kernel kernel; - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1); - kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.)); + kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IfcGeom::IteratorSettings::SEW_SHELLS) ? 1000 : -1); + kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES) ? (settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); std::pair length_unit = kernel.initializeUnits(project->UnitsInContext()); if (instance->is(IfcSchema::Type::IfcProduct)) { @@ -269,13 +269,13 @@ struct ShapeRTTI : public boost::static_visitor // First, try to find a representation based on the settings for (IfcSchema::IfcRepresentation::list::it it = reps->begin(); it != reps->end(); ++it) { IfcSchema::IfcRepresentation* rep = *it; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { if (rep->RepresentationIdentifier() == "Body") { ifc_representation = rep; break; } } - if (settings.include_curves()) { + if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) { if (rep->RepresentationIdentifier() == "Plan" || rep->RepresentationIdentifier() == "Axis") { ifc_representation = rep; break; @@ -293,12 +293,12 @@ struct ShapeRTTI : public boost::static_visitor // TODO: Remove redundancy with IfcGeomIterator.h if (context->hasContextType()) { std::set context_types; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { context_types.insert("model"); context_types.insert("design"); context_types.insert("model view"); } - if (settings.include_curves()) { + if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) { context_types.insert("plan"); } @@ -347,11 +347,11 @@ struct ShapeRTTI : public boost::static_visitor if (!brep) { throw IfcParse::IfcException("Failed to process shape"); } - if (settings.use_brep_data()) { + if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) { IfcGeom::SerializedElement* serialization = new IfcGeom::SerializedElement(*brep); delete brep; return serialization; - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) { IfcGeom::TriangulationElement* triangulation = new IfcGeom::TriangulationElement(*brep); delete brep; return triangulation; @@ -366,9 +366,9 @@ struct ShapeRTTI : public boost::static_visitor IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), IfcSchema::Type::ToString(instance->type())); IfcGeom::Representation::BRep brep(element_settings, instance->entity->id(), shapes); try { - if (settings.use_brep_data()) { + if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) { return new IfcGeom::Representation::Serialization(brep); - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) { return new IfcGeom::Representation::Triangulation(brep); } } catch (...) { diff --git a/test/input/large_offset.ifc b/test/input/large_offset.ifc new file mode 100644 index 0000000000..41beaf110e --- /dev/null +++ b/test/input/large_offset.ifc @@ -0,0 +1,1083 @@ +ISO-10303-21; +HEADER; + +/****************************************************************************************** +* STEP Physical File produced by: The EXPRESS Data Manager Version 5.02.0100.07 : 28 Aug 2013 +* Module: EDMstepFileFactory/EDMstandAlone +* Creation date: Thu Nov 19 15:05:44 2015 +* Host: DESKTOP-O02U94U +* Database: C:\Users\ANAMOU~1\AppData\Local\Temp\{E0C3FBC3-4736-4E0A-9D2F-C87BBC395BA5}\ifc +* Database version: 5507 +* Database creation date: Thu Nov 19 15:05:36 2015 +* Schema: IFC4 +* Model: DataRepository.ifc +* Model creation date: Thu Nov 19 15:05:37 2015 +* Header model: DataRepository.ifc_HeaderModel +* Header model creation date: Thu Nov 19 15:05:37 2015 +* EDMuser: sdai-user +* EDMgroup: sdai-group +* License ID and type: 5605 : Permanent license. Expiry date: +* EDMstepFileFactory options: 020000 +******************************************************************************************/ +FILE_DESCRIPTION(('ViewDefinition [CoordinationView_V2.0]'),'2;1'); +FILE_NAME('12370','2015-11-19T15:05:44',(''),(''),'The EXPRESS Data Manager Version 5.02.0100.07 : 28 Aug 2013','20150220_1215(x64) - Exporter 16.2.0.0 - Alternate UI 16.2.0.0',''); +FILE_SCHEMA(('IFC4')); +ENDSEC; + +DATA; +#1= IFCORGANIZATION($,'Autodesk Revit LT 2016 (ENU)',$,$,$); +#5= IFCAPPLICATION(#1,'2016','Autodesk Revit LT 2016 (ENU)','Revit'); +#6= IFCCARTESIANPOINT((0.,0.,0.)); +#10= IFCCARTESIANPOINT((0.,0.)); +#12= IFCDIRECTION((1.,0.,0.)); +#14= IFCDIRECTION((-1.,0.,0.)); +#16= IFCDIRECTION((0.,1.,0.)); +#18= IFCDIRECTION((0.,-1.,0.)); +#20= IFCDIRECTION((0.,0.,1.)); +#22= IFCDIRECTION((0.,0.,-1.)); +#24= IFCDIRECTION((1.,0.)); +#26= IFCDIRECTION((-1.,0.)); +#28= IFCDIRECTION((0.,1.)); +#30= IFCDIRECTION((0.,-1.)); +#32= IFCAXIS2PLACEMENT3D(#6,$,$); +#33= IFCLOCALPLACEMENT(#1853,#32); +#36= IFCPERSON($,'Moural','Ana',$,$,$,$,$); +#38= IFCORGANIZATION($,'PG Campus \X2\00C5\X0\s','A - Arkitekt',$,$); +#39= IFCPERSONANDORGANIZATION(#36,#38,$); +#42= IFCOWNERHISTORY(#39,#5,$,.NOCHANGE.,$,$,$,0); +#43= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.); +#44= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.); +#45= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.); +#46= IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.); +#47= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.); +#48= IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0); +#49= IFCMEASUREWITHUNIT(IFCRATIOMEASURE(0.0174532925199433),#47); +#50= IFCCONVERSIONBASEDUNIT(#48,.PLANEANGLEUNIT.,'DEGREE',#49); +#52= IFCSIUNIT(*,.MASSUNIT.,.KILO.,.GRAM.); +#53= IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.); +#54= IFCSIUNIT(*,.FREQUENCYUNIT.,$,.HERTZ.); +#55= IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.KELVIN.); +#56= IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.DEGREE_CELSIUS.); +#57= IFCDERIVEDUNITELEMENT(#52,1); +#58= IFCDERIVEDUNITELEMENT(#55,-1); +#59= IFCDERIVEDUNITELEMENT(#53,-3); +#60= IFCDERIVEDUNIT((#57,#58,#59),.THERMALTRANSMITTANCEUNIT.,$); +#62= IFCSIUNIT(*,.LENGTHUNIT.,.DECI.,.METRE.); +#63= IFCDERIVEDUNITELEMENT(#44,3); +#64= IFCDERIVEDUNITELEMENT(#53,-1); +#65= IFCDERIVEDUNIT((#63,#64),.VOLUMETRICFLOWRATEUNIT.,$); +#67= IFCSIUNIT(*,.ELECTRICCURRENTUNIT.,$,.AMPERE.); +#68= IFCSIUNIT(*,.ELECTRICVOLTAGEUNIT.,$,.VOLT.); +#69= IFCSIUNIT(*,.POWERUNIT.,$,.WATT.); +#70= IFCSIUNIT(*,.FORCEUNIT.,.KILO.,.NEWTON.); +#71= IFCSIUNIT(*,.ILLUMINANCEUNIT.,$,.LUX.); +#72= IFCSIUNIT(*,.LUMINOUSFLUXUNIT.,$,.LUMEN.); +#73= IFCSIUNIT(*,.LUMINOUSINTENSITYUNIT.,$,.CANDELA.); +#74= IFCDERIVEDUNITELEMENT(#52,-1); +#75= IFCDERIVEDUNITELEMENT(#44,-2); +#76= IFCDERIVEDUNITELEMENT(#53,3); +#77= IFCDERIVEDUNITELEMENT(#72,1); +#78= IFCDERIVEDUNIT((#74,#75,#76,#77),.USERDEFINED.,'Luminous Efficacy'); +#80= IFCDERIVEDUNITELEMENT(#44,1); +#81= IFCDERIVEDUNITELEMENT(#53,-1); +#82= IFCDERIVEDUNIT((#80,#81),.LINEARVELOCITYUNIT.,$); +#84= IFCSIUNIT(*,.PRESSUREUNIT.,$,.PASCAL.); +#85= IFCDERIVEDUNITELEMENT(#44,-2); +#86= IFCDERIVEDUNITELEMENT(#52,1); +#87= IFCDERIVEDUNITELEMENT(#53,-2); +#88= IFCDERIVEDUNIT((#85,#86,#87),.USERDEFINED.,'Friction Loss'); +#90= IFCUNITASSIGNMENT((#43,#45,#46,#50,#52,#53,#54,#56,#60,#65,#67,#68,#69,#70,#71,#72,#73,#78,#82,#84,#88)); +#92= IFCAXIS2PLACEMENT3D(#6,$,$); +#93= IFCDIRECTION((0.0916772417912353,0.995788774458495)); +#95= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,0.01,#92,#93); +#98= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#95,$,.GRAPH_VIEW.,$); +#100= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#95,$,.MODEL_VIEW.,$); +#101= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Box','Model',*,*,*,*,#95,$,.MODEL_VIEW.,$); +#102= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('FootPrint','Model',*,*,*,*,#95,$,.MODEL_VIEW.,$); +#103= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Annotation',3,0.01,#92,#93); +#104= IFCGEOMETRICREPRESENTATIONSUBCONTEXT($,'Annotation',*,*,*,*,#103,0.01,.PLAN_VIEW.,$); +#106= IFCPROJECT('3o91zj$Gr6cQ_i1EP5O_01',#42,'12370',$,$,'14323','02',(#95,#103),#90); +#117= IFCPOSTALADDRESS($,$,$,$,('Forprosjekt'),$,'','As','','Norge'); +#121= IFCBUILDING('3o91zj$Gr6cQ_i1EP5O_00',#42,'091',$,$,#33,$,'091',.ELEMENT.,$,$,#117); +#131= IFCCARTESIANPOINT((0.,0.,-4450.)); +#133= IFCAXIS2PLACEMENT3D(#131,$,$); +#2287= IFCRELVOIDSELEMENT('3EsgTT6fn7Xw9SBqFdrMkV',#42,$,$,#1066,#2284); +#1898= IFCRELDEFINESBYPROPERTIES('3tofk5JcvBsfvwT1fkqAen',#42,$,$,(#1854),#1886); +#138= IFCAXIS2PLACEMENT3D(#6,$,$); +#139= IFCLOCALPLACEMENT(#33,#138); +#140= IFCBUILDINGSTOREY('3o91zj$Gr6cQ_i1EQwd1x6',#42,'PLAN 01',$,$,#139,$,'PLAN 01',.ELEMENT.,0.); +#142= IFCCARTESIANPOINT((0.,0.,3060.)); +#144= IFCAXIS2PLACEMENT3D(#142,$,$); +#145= IFCLOCALPLACEMENT(#33,#144); +#146= IFCBUILDINGSTOREY('3o91zj$Gr6cQ_i1EQwc5Gk',#42,'PLAN 02',$,$,#145,$,'PLAN 02',.ELEMENT.,3060.); +#255= IFCAXIS2PLACEMENT3D(#6,$,$); +#2284= IFCOPENINGELEMENT('3n3el7tsPBORtUY8_VoM22',#42,'Basic Wall:V10:4932686',$,'Opening',#2283,#2277,$,.OPENING.); +#257= IFCCARTESIANPOINT((-215.482203135574,-117.851130197757)); +#259= IFCCARTESIANPOINT((284.517796864423,-117.851130197757)); +#261= IFCPOLYLINE((#257,#259)); +#263= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#261); +#265= IFCCARTESIANPOINT((284.517796864423,-117.851130197757)); +#267= IFCCARTESIANPOINT((-69.0355937288516,235.702260395512)); +#269= IFCPOLYLINE((#265,#267)); +#271= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#269); +#272= IFCCARTESIANPOINT((284.517796864429,-117.851130197759)); +#274= IFCDIRECTION((0.707106781186553,0.707106781186553)); +#276= IFCAXIS2PLACEMENT2D(#272,#274); +#277= IFCCIRCLE(#276,500.000000000003); +#278= IFCTRIMMEDCURVE(#277,(IFCPARAMETERVALUE(90.0000000000003)),(IFCPARAMETERVALUE(135.)),.T.,.PARAMETER.); +#281= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#278); +#282= IFCCOMPOSITECURVE((#263,#271,#281),.F.); +#287= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'ARK',#282); +#290= IFCCARTESIANPOINT((-117.851130197759,284.517796864426,0.)); +#292= IFCDIRECTION((0.707106781186546,-0.707106781186549,0.)); +#294= IFCAXIS2PLACEMENT3D(#290,#20,#292); +#295= IFCEXTRUDEDAREASOLID(#287,#294,#20,1000.); +#296= IFCCARTESIANPOINT((-22.2701322115385,-16.1538461538461)); +#298= IFCCARTESIANPOINT((-15.7677283653846,-16.1538461538461)); +#300= IFCCARTESIANPOINT((-10.1427283653846,-0.769230769230751)); +#302= IFCCARTESIANPOINT((10.1337139423077,-0.769230769230751)); +#304= IFCCARTESIANPOINT((15.7707331730769,-16.1538461538461)); +#306= IFCCARTESIANPOINT((22.2731370192308,-16.1538461538461)); +#308= IFCCARTESIANPOINT((2.62169471153847,33.0769230769231)); +#310= IFCCARTESIANPOINT((-2.61868990384616,33.0769230769231)); +#312= IFCPOLYLINE((#296,#298,#300,#302,#304,#306,#308,#310,#296)); +#314= IFCCARTESIANPOINT((-7.88311298076925,5.38461538461539)); +#316= IFCCARTESIANPOINT((-3.06340144230768,18.5456730769231)); +#318= IFCCARTESIANPOINT((0.0015024038461509,26.9230769230769)); +#320= IFCCARTESIANPOINT((3.45102163461539,17.4879807692308)); +#322= IFCCARTESIANPOINT((7.88611778846155,5.38461538461539)); +#324= IFCPOLYLINE((#314,#316,#318,#320,#322,#314)); +#326= IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,'ARK',#312,(#324)); +#328= IFCCARTESIANPOINT((-171.980586302626,295.540377228824,1000.)); +#330= IFCAXIS2PLACEMENT3D(#328,$,$); +#331= IFCEXTRUDEDAREASOLID(#326,#330,#20,10.); +#332= IFCCARTESIANPOINT((-23.1072874493927,-22.0657262145749)); +#334= IFCCARTESIANPOINT((-16.9534412955466,-22.0657262145749)); +#336= IFCCARTESIANPOINT((-16.9534412955466,-0.527264676113383)); +#338= IFCCARTESIANPOINT((-9.52555668016196,-0.527264676113383)); +#340= IFCCARTESIANPOINT((-5.95584514170041,-0.743610829959519)); +#342= IFCCARTESIANPOINT((-3.02916244939272,-1.91548582995952)); +#344= IFCCARTESIANPOINT((0.22203947368421,-5.1065915991903)); +#346= IFCCARTESIANPOINT((4.84944331983806,-11.861399291498)); +#348= IFCCARTESIANPOINT((11.2556933198381,-22.0657262145749)); +#350= IFCCARTESIANPOINT((18.4071356275304,-22.0657262145749)); +#352= IFCCARTESIANPOINT((10.1980010121458,-8.72438006072877)); +#354= IFCCARTESIANPOINT((5.21002024291498,-2.39024544534416)); +#356= IFCCARTESIANPOINT((1.71242408906881,0.241966093117401)); +#358= IFCCARTESIANPOINT((12.0189144736842,4.82129301619432)); +#360= IFCCARTESIANPOINT((15.3542510121457,13.6914853238866)); +#362= IFCCARTESIANPOINT((13.3410298582996,21.1373987854251)); +#364= IFCCARTESIANPOINT((7.95641447368421,25.8369180161943)); +#366= IFCCARTESIANPOINT((-1.89334514170039,27.1650430161943)); +#368= IFCCARTESIANPOINT((-23.1072874493927,27.1650430161943)); +#370= IFCPOLYLINE((#332,#334,#336,#338,#340,#342,#344,#346,#348,#350,#352,#354,#356,#358,#360,#362,#364,#366,#368,#332)); +#372= IFCCARTESIANPOINT((-16.9534412955466,5.62658147773276)); +#374= IFCCARTESIANPOINT((-16.9534412955466,21.0111968623482)); +#376= IFCCARTESIANPOINT((-1.62892206477732,21.0111968623482)); +#378= IFCCARTESIANPOINT((6.59824139676112,18.8837930161943)); +#380= IFCCARTESIANPOINT((9.20040485829959,13.4631199392712)); +#382= IFCCARTESIANPOINT((7.8362221659919,9.28643724696353)); +#384= IFCCARTESIANPOINT((3.84583755060729,6.49797570850204)); +#386= IFCCARTESIANPOINT((-3.1794028340081,5.62658147773276)); +#388= IFCPOLYLINE((#372,#374,#376,#378,#380,#382,#384,#386,#372)); +#390= IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,'ARK',#370,(#388)); +#392= IFCCARTESIANPOINT((-120.025642603233,301.452257289553,1000.)); +#394= IFCAXIS2PLACEMENT3D(#392,$,$); +#395= IFCEXTRUDEDAREASOLID(#390,#394,#20,10.); +#396= IFCCARTESIANPOINT((-16.9401041666667,-24.4000400641025)); +#398= IFCCARTESIANPOINT((-10.7862580128205,-24.4000400641025)); +#400= IFCCARTESIANPOINT((-10.7862580128205,-7.47696314102559)); +#402= IFCCARTESIANPOINT((-2.49298878205128,0.43169070512825)); +#404= IFCCARTESIANPOINT((16.3050881410257,-24.4000400641025)); +#406= IFCCARTESIANPOINT((23.8291266025641,-24.4000400641025)); +#408= IFCCARTESIANPOINT((1.8699919871795,4.5903445512821)); +#410= IFCCARTESIANPOINT((23.0598958333334,24.8307291666667)); +#412= IFCCARTESIANPOINT((14.4541266025641,24.8307291666667)); +#414= IFCCARTESIANPOINT((-10.7862580128205,0.732171474359006)); +#416= IFCCARTESIANPOINT((-10.7862580128205,24.8307291666667)); +#418= IFCCARTESIANPOINT((-16.9401041666667,24.8307291666667)); +#420= IFCPOLYLINE((#396,#398,#400,#402,#404,#406,#408,#410,#412,#414,#416,#418,#396)); +#422= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'ARK',#420); +#423= IFCCARTESIANPOINT((-76.9620566551901,303.78657113908,1000.)); +#425= IFCAXIS2PLACEMENT3D(#423,$,$); +#426= IFCEXTRUDEDAREASOLID(#422,#425,#20,10.); +#427= IFCCOLOURRGB($,0.,1.,0.); +#428= IFCSURFACESTYLERENDERING(#427,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#429= IFCSURFACESTYLE('NULPUNKT - ARK',.BOTH.,(#428)); +#431= IFCPRESENTATIONSTYLEASSIGNMENT((#429)); +#433= IFCSTYLEDITEM(#295,(#431),$); +#436= IFCCOLOURRGB($,0.498039215686275,0.498039215686275,0.498039215686275); +#437= IFCSURFACESTYLERENDERING(#436,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#438= IFCSURFACESTYLE('Default',.BOTH.,(#437)); +#440= IFCPRESENTATIONSTYLEASSIGNMENT((#438)); +#442= IFCSTYLEDITEM(#331,(#440),$); +#445= IFCSTYLEDITEM(#395,(#440),$); +#448= IFCSTYLEDITEM(#426,(#440),$); +#451= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#295,#331,#395,#426)); +#458= IFCCARTESIANPOINT((-14.852961874911,14.1421356237286)); +#460= IFCCARTESIANPOINT((-0.,28.9950974986374)); +#462= IFCPOLYLINE((#458,#460)); +#464= IFCCARTESIANPOINT((-28.9950974986419,28.2842712474597)); +#466= IFCCARTESIANPOINT((-0.,57.2793687460993)); +#468= IFCPOLYLINE((#464,#466)); +#470= IFCCARTESIANPOINT((-43.1372331223728,42.4264068711906)); +#472= IFCCARTESIANPOINT((-0.,85.5636399935611)); +#474= IFCPOLYLINE((#470,#472)); +#476= IFCCARTESIANPOINT((-57.2793687461036,56.5685424949217)); +#478= IFCCARTESIANPOINT((-0.,113.847911241023)); +#480= IFCPOLYLINE((#476,#478)); +#482= IFCCARTESIANPOINT((-71.4215043698345,70.7106781186527)); +#484= IFCCARTESIANPOINT((-0.,142.132182488485)); +#486= IFCPOLYLINE((#482,#484)); +#488= IFCCARTESIANPOINT((-85.5636399935654,84.8528137423838)); +#490= IFCCARTESIANPOINT((-0.,170.416453735947)); +#492= IFCPOLYLINE((#488,#490)); +#494= IFCCARTESIANPOINT((-99.7057756172962,98.9949493661148)); +#496= IFCCARTESIANPOINT((-0.,198.700724983409)); +#498= IFCPOLYLINE((#494,#496)); +#500= IFCCARTESIANPOINT((-113.847911241027,113.137084989846)); +#502= IFCCARTESIANPOINT((-0.,226.984996230871)); +#504= IFCPOLYLINE((#500,#502)); +#506= IFCCARTESIANPOINT((-127.634633739169,127.634633739166)); +#508= IFCCARTESIANPOINT((-0.,255.269267478333)); +#510= IFCPOLYLINE((#506,#508)); +#512= IFCCARTESIANPOINT((-141.7767693629,141.776769362897)); +#514= IFCCARTESIANPOINT((-0.,283.553538725795)); +#516= IFCPOLYLINE((#512,#514)); +#518= IFCCARTESIANPOINT((-155.918904986631,155.918904986628)); +#520= IFCCARTESIANPOINT((-0.,311.837809973257)); +#522= IFCPOLYLINE((#518,#520)); +#524= IFCCARTESIANPOINT((-166.170093578841,173.95198764188)); +#526= IFCCARTESIANPOINT((-0.,340.122081220719)); +#528= IFCPOLYLINE((#524,#526)); +#530= IFCCARTESIANPOINT((-184.203176234092,184.20317623409)); +#532= IFCCARTESIANPOINT((-0.,368.40635246818)); +#534= IFCPOLYLINE((#530,#532)); +#536= IFCCARTESIANPOINT((-198.345311857823,198.345311857821)); +#538= IFCCARTESIANPOINT((-0.,396.690623715642)); +#540= IFCPOLYLINE((#536,#538)); +#542= IFCCARTESIANPOINT((-212.487447481554,212.487447481552)); +#544= IFCCARTESIANPOINT((-0.,424.974894963105)); +#546= IFCPOLYLINE((#542,#544)); +#548= IFCCARTESIANPOINT((-226.629583105285,226.629583105283)); +#550= IFCCARTESIANPOINT((-0.,453.259166210566)); +#552= IFCPOLYLINE((#548,#550)); +#554= IFCCARTESIANPOINT((-240.771718729016,240.771718729014)); +#556= IFCCARTESIANPOINT((-0.,481.543437458028)); +#558= IFCPOLYLINE((#554,#556)); +#560= IFCCARTESIANPOINT((-254.913854352747,254.913854352745)); +#562= IFCCARTESIANPOINT((-9.9262488315132,499.901459873978)); +#564= IFCPOLYLINE((#560,#562)); +#566= IFCCARTESIANPOINT((-269.055989976478,269.055989976476)); +#568= IFCCARTESIANPOINT((-39.6897451674856,498.422234785468)); +#570= IFCPOLYLINE((#566,#568)); +#572= IFCCARTESIANPOINT((-283.198125600209,283.198125600207)); +#574= IFCCARTESIANPOINT((-71.5408043081512,494.855446892265)); +#576= IFCPOLYLINE((#572,#574)); +#578= IFCCARTESIANPOINT((-297.34026122394,297.340261223938)); +#580= IFCCARTESIANPOINT((-106.058351323186,488.622171124692)); +#582= IFCPOLYLINE((#578,#580)); +#584= IFCCARTESIANPOINT((-311.482396847671,311.482396847669)); +#586= IFCCARTESIANPOINT((-144.214000388474,478.750793306866)); +#588= IFCPOLYLINE((#584,#586)); +#590= IFCCARTESIANPOINT((-325.624532471401,325.6245324714)); +#592= IFCCARTESIANPOINT((-187.897760009465,463.351304933336)); +#594= IFCPOLYLINE((#590,#592)); +#596= IFCCARTESIANPOINT((-339.766668095133,339.766668095131)); +#598= IFCCARTESIANPOINT((-241.998517598497,437.534818591767)); +#600= IFCPOLYLINE((#596,#598)); +#602= IFCCARTESIANPOINT((-0.,481.543437458028)); +#604= IFCCARTESIANPOINT((18.1278360413173,499.671273499347)); +#606= IFCPOLYLINE((#602,#604)); +#608= IFCAXIS2PLACEMENT2D(#10,#24); +#609= IFCCIRCLE(#608,500.); +#610= IFCCARTESIANPOINT((353.553390593277,353.553390593271)); +#612= IFCCARTESIANPOINT((-353.553390593274,-353.553390593274)); +#614= IFCPOLYLINE((#610,#612)); +#616= IFCCARTESIANPOINT((353.553390593271,-353.553390593276)); +#618= IFCCARTESIANPOINT((-353.553390593275,353.553390593273)); +#620= IFCPOLYLINE((#616,#618)); +#622= IFCCARTESIANPOINT((750.,-0.)); +#624= IFCCARTESIANPOINT((-750.,0.)); +#626= IFCPOLYLINE((#622,#624)); +#628= IFCCARTESIANPOINT((-0.,-750.)); +#630= IFCCARTESIANPOINT((-0.,750.)); +#632= IFCPOLYLINE((#628,#630)); +#634= IFCGEOMETRICSET((#462,#468,#474,#480,#486,#492,#498,#504,#510,#516,#522,#528,#534,#540,#546,#552,#558,#564,#570,#576,#582,#588,#594,#600,#606,#609,#614,#620,#626,#632)); +#636= IFCSHAPEREPRESENTATION(#104,'FootPrint','GeometricSet',(#634)); +#639= IFCAXIS2PLACEMENT3D(#6,$,$); +#640= IFCREPRESENTATIONMAP(#639,#451); +#644= IFCREPRESENTATIONMAP(#639,#636); +#646= IFCBUILDINGELEMENTPROXYTYPE('19G2kjMqT2bw6US8_6I3Jw',#42,'ARK',$,$,(#798,#809),(#640,#644),'235751',$,.NOTDEFINED.); +#650= IFCMATERIAL('NULPUNKT - ARK',$,$); +#657= IFCPRESENTATIONSTYLEASSIGNMENT((#429)); +#659= IFCSTYLEDITEM($,(#657),$); +#661= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#659)); +#664= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#661),#650); +#668= IFCMATERIAL('Default',$,$); +#669= IFCPRESENTATIONSTYLEASSIGNMENT((#438)); +#671= IFCSTYLEDITEM($,(#669),$); +#673= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#671)); +#675= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#673),#668); +#679= IFCMATERIALLIST((#650,#668)); +#681= IFCCLASSIFICATION('http://www.csiorg.net/uniformat','1998',$,'Uniformat',$,$,$); +#684= IFCCARTESIANTRANSFORMATIONOPERATOR3D($,$,#6,1.,$); +#685= IFCMAPPEDITEM(#640,#684); +#687= IFCSHAPEREPRESENTATION(#100,'Body','MappedRepresentation',(#685)); +#689= IFCMAPPEDITEM(#644,#684); +#691= IFCSHAPEREPRESENTATION(#104,'FootPrint','MappedRepresentation',(#689)); +#693= IFCPRODUCTDEFINITIONSHAPE($,$,(#687,#691)); +#699= IFCAXIS2PLACEMENT3D(#6,$,$); +#700= IFCLOCALPLACEMENT(#139,#699); +#701= IFCBUILDINGELEMENTPROXY('19G2kjMqT2bw6US8_6I2Vy',#42,'Prosjekt nullpunkt - ARK:ARK:232417',$,'ARK',#700,#693,'232417',$); +#716= IFCMATERIALLIST((#650,#668)); +#718= IFCPROPERTYSINGLEVALUE('Host',$,IFCTEXT('Level : PLAN 01'),$); +#724= IFCPROPERTYSINGLEVALUE('Level',$,IFCLABEL('Level: PLAN 01'),$); +#725= IFCPROPERTYSINGLEVALUE('Moves With Nearby Elements',$,IFCBOOLEAN(.F.),$); +#726= IFCPROPERTYSINGLEVALUE('Offset',$,IFCLENGTHMEASURE(0.),$); +#727= IFCPROPERTYSINGLEVALUE('Phase Created',$,IFCLABEL('New Construction'),$); +#728= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(0.800782485703027),$); +#729= IFCPROPERTYSINGLEVALUE('H\X2\00F8\X0\yde over prosjektnullpunkt',$,IFCLENGTHMEASURE(5000.),$); +#730= IFCPROPERTYSINGLEVALUE('H\X2\00F8\X0\yde under prosjektnullpunkt',$,IFCLENGTHMEASURE(1000.),$); +#731= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.0981970030347725),$); +#732= IFCPROPERTYSINGLEVALUE('Design Option',$,IFCLABEL('Akselinier (primary)'),$); +#733= IFCPROPERTYSINGLEVALUE('Mark',$,IFCTEXT('1'),$); +#734= IFCPROPERTYSINGLEVALUE('Reference Nr. On/Off',$,IFCBOOLEAN(.F.),$); +#735= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Generic Models'),$); +#736= IFCPROPERTYSINGLEVALUE('Family',$,IFCLABEL('Prosjekt nullpunkt - ARK: ARK'),$); +#737= IFCPROPERTYSINGLEVALUE('Family and Type',$,IFCLABEL('Prosjekt nullpunkt - ARK: ARK'),$); +#738= IFCPROPERTYSINGLEVALUE('Type',$,IFCLABEL('Prosjekt nullpunkt - ARK: ARK'),$); +#739= IFCPROPERTYSINGLEVALUE('Type Id',$,IFCLABEL('Prosjekt nullpunkt - ARK: ARK'),$); +#740= IFCPROPERTYSINGLEVALUE('Assembly Code',$,IFCTEXT(''),$); +#741= IFCPROPERTYSINGLEVALUE('Assembly Description',$,IFCTEXT(''),$); +#742= IFCPROPERTYSINGLEVALUE('Code Name',$,IFCTEXT(''),$); +#743= IFCPROPERTYSINGLEVALUE('Description',$,IFCTEXT('Prosjekt nullpunkt'),$); +#744= IFCPROPERTYSINGLEVALUE('Model',$,IFCTEXT(''),$); +#745= IFCPROPERTYSINGLEVALUE('OmniClass Number',$,IFCTEXT(''),$); +#746= IFCPROPERTYSINGLEVALUE('OmniClass Title',$,IFCTEXT(''),$); +#747= IFCPROPERTYSINGLEVALUE('Type Comments',$,IFCTEXT(''),$); +#748= IFCPROPERTYSINGLEVALUE('Type Name',$,IFCTEXT('ARK'),$); +#749= IFCPROPERTYSINGLEVALUE('Family Name',$,IFCTEXT('Prosjekt nullpunkt - ARK'),$); +#750= IFCPROPERTYSET('19G2kjMqT2bw6UTfk6I2Vy',#42,'Constraints',$,(#718,#724,#725,#726)); +#761= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTvk6I2Vy',#42,$,$,(#701),#750); +#765= IFCPROPERTYSET('19G2kjMqT2bw6UTes6I2Vy',#42,'Dimensions',$,(#728,#729,#730,#731)); +#771= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTus6I2Vy',#42,$,$,(#701),#765); +#774= IFCPROPERTYSET('19G2kjMqT2bw6UTew6I2Vy',#42,'Identity Data',$,(#732,#733,#734)); +#779= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTuw6I2Vy',#42,$,$,(#701),#774); +#782= IFCPROPERTYSET('04ex9yUQn3xgXt9j78lgww',#42,'Other',$,(#735,#736,#737,#738,#739)); +#789= IFCRELDEFINESBYPROPERTIES('0BPTyWIbPEk9rSL4IWNn9D',#42,$,$,(#701),#782); +#792= IFCPROPERTYSET('19G2kjMqT2bw6UTe26I2Vy',#42,'Phasing',$,(#727)); +#795= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTu26I2Vy',#42,$,$,(#701),#792); +#798= IFCPROPERTYSET('19G2kjMqT2bw6UTew6I3Jw',#42,'Identity Data',$,(#740,#741,#742,#743,#744,#745,#746,#747,#748)); +#809= IFCPROPERTYSET('0Rca49yqv2WOWW$EUHuWC8',#42,'Other',$,(#735,#749)); +#815= IFCAXIS2PLACEMENT3D(#6,$,$); +#816= IFCLOCALPLACEMENT(#139,#815); +#817= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#819= IFCCARTESIANPOINT((23.3333333333334,-11.6666666666665)); +#821= IFCPOLYLINE((#817,#819)); +#823= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#821); +#824= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#826= IFCAXIS2PLACEMENT2D(#824,#28); +#827= IFCCIRCLE(#826,35.); +#828= IFCTRIMMEDCURVE(#827,(IFCPARAMETERVALUE(269.999999999999)),(IFCPARAMETERVALUE(359.999999999999)),.T.,.PARAMETER.); +#831= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#828); +#832= IFCCARTESIANPOINT((-11.6666666666667,23.3333333333335)); +#834= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#836= IFCPOLYLINE((#832,#834)); +#838= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#836); +#839= IFCCOMPOSITECURVE((#823,#831,#838),.F.); +#844= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'Custom',#839); +#845= IFCCARTESIANPOINT((11.6666666666665,-11.6666666666667,0.)); +#847= IFCAXIS2PLACEMENT3D(#845,#20,#18); +#848= IFCEXTRUDEDAREASOLID(#844,#847,#20,0.8); +#849= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#851= IFCCARTESIANPOINT((23.3333333333334,-11.6666666666665)); +#853= IFCPOLYLINE((#849,#851)); +#855= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#853); +#856= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#858= IFCAXIS2PLACEMENT2D(#856,#28); +#859= IFCCIRCLE(#858,35.); +#860= IFCTRIMMEDCURVE(#859,(IFCPARAMETERVALUE(269.999999999999)),(IFCPARAMETERVALUE(359.999999999999)),.T.,.PARAMETER.); +#863= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#860); +#864= IFCCARTESIANPOINT((-11.6666666666667,23.3333333333335)); +#866= IFCCARTESIANPOINT((-11.6666666666666,-11.6666666666665)); +#868= IFCPOLYLINE((#864,#866)); +#870= IFCCOMPOSITECURVESEGMENT(.CONTINUOUS.,.T.,#868); +#871= IFCCOMPOSITECURVE((#855,#863,#870),.F.); +#876= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'Custom',#871); +#877= IFCCARTESIANPOINT((-11.6666666666669,11.6666666666668,0.)); +#879= IFCAXIS2PLACEMENT3D(#877,#20,#16); +#880= IFCEXTRUDEDAREASOLID(#876,#879,#20,0.8); +#881= IFCCOLOURRGB($,0.,0.,0.); +#882= IFCSURFACESTYLERENDERING(#881,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#883= IFCSURFACESTYLE('Black',.BOTH.,(#882)); +#885= IFCPRESENTATIONSTYLEASSIGNMENT((#883)); +#887= IFCSTYLEDITEM(#848,(#885),$); +#890= IFCSTYLEDITEM(#880,(#885),$); +#893= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#848,#880)); +#895= IFCPRODUCTDEFINITIONSHAPE($,$,(#893)); +#898= IFCSLAB('19G2kjMqT2bw6US8_6I2V$',#42,'SurveyMarker:Custom:232418',$,'SurveyMarker:Custom',#816,#895,'232418',.FLOOR.); +#901= IFCMATERIAL('Black',$,$); +#902= IFCPRESENTATIONSTYLEASSIGNMENT((#883)); +#904= IFCSTYLEDITEM($,(#902),$); +#906= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#904)); +#908= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#906),#901); +#912= IFCPROPERTYSINGLEVALUE('Host',$,IFCTEXT('Level : PLAN 01'),$); +#913= IFCPROPERTYSINGLEVALUE('Moves With Grids',$,IFCBOOLEAN(.T.),$); +#914= IFCPROPERTYSINGLEVALUE('Rebar Cover - Bottom Face',$,IFCLABEL('Rebar Cover Settings: Rebar Cover 1'),$); +#915= IFCPROPERTYSINGLEVALUE('Rebar Cover - Other Faces',$,IFCLABEL('Rebar Cover Settings: Rebar Cover 1'),$); +#916= IFCPROPERTYSINGLEVALUE('Rebar Cover - Top Face',$,IFCLABEL('Rebar Cover Settings: Rebar Cover 1'),$); +#917= IFCPROPERTYSINGLEVALUE('Switch Marker',$,IFCBOOLEAN(.T.),$); +#918= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(0.00192397103712917),$); +#919= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(1.53930324981553E-6),$); +#920= IFCPROPERTYSINGLEVALUE('Host Family Description',$,IFCTEXT('Prosjekt nullpunkt'),$); +#921= IFCPROPERTYSINGLEVALUE('Reference Nr.',$,IFCTEXT('1'),$); +#922= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Structural Foundations'),$); +#923= IFCPROPERTYSINGLEVALUE('Family',$,IFCLABEL('SurveyMarker: Custom'),$); +#924= IFCPROPERTYSINGLEVALUE('Family and Type',$,IFCLABEL('SurveyMarker: Custom'),$); +#925= IFCPROPERTYSINGLEVALUE('Type',$,IFCLABEL('SurveyMarker: Custom'),$); +#926= IFCPROPERTYSINGLEVALUE('Type Id',$,IFCLABEL('SurveyMarker: Custom'),$); +#927= IFCPROPERTYSINGLEVALUE('Circle',$,IFCBOOLEAN(.T.),$); +#928= IFCPROPERTYSINGLEVALUE('Square',$,IFCBOOLEAN(.T.),$); +#929= IFCPROPERTYSINGLEVALUE('Fill',$,IFCBOOLEAN(.T.),$); +#930= IFCPROPERTYSINGLEVALUE('Length',$,IFCLENGTHMEASURE(35.),$); +#931= IFCPROPERTYSINGLEVALUE('Scale',$,IFCLENGTHMEASURE(35.),$); +#932= IFCPROPERTYSINGLEVALUE('Width',$,IFCLENGTHMEASURE(35.),$); +#933= IFCPROPERTYSINGLEVALUE('Type Comments',$,IFCTEXT('SurveyMarker'),$); +#934= IFCPROPERTYSINGLEVALUE('Type Name',$,IFCTEXT('Custom'),$); +#935= IFCPROPERTYSINGLEVALUE('Family Name',$,IFCTEXT('SurveyMarker'),$); +#936= IFCPROPERTYSET('19G2kjMqT2bw6UTfk6I2V$',#42,'Constraints',$,(#724,#726,#912,#913)); +#940= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTvk6I2V$',#42,$,$,(#898),#936); +#944= IFCPROPERTYSET('19G2kjMqT2bw6UTes6I2V$',#42,'Dimensions',$,(#918,#919)); +#948= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTus6I2V$',#42,$,$,(#898),#944); +#951= IFCPROPERTYSET('19G2kjMqT2bw6UTeg6I2V$',#42,'Graphics',$,(#917)); +#954= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTug6I2V$',#42,$,$,(#898),#951); +#957= IFCPROPERTYSET('19G2kjMqT2bw6UTew6I2V$',#42,'Identity Data',$,(#732,#734,#920,#921)); +#961= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTuw6I2V$',#42,$,$,(#898),#957); +#964= IFCPROPERTYSET('2KSntZC_j7LBUsDOKI4aYw',#42,'Other',$,(#922,#923,#924,#925,#926)); +#971= IFCRELDEFINESBYPROPERTIES('24qsqZIqL3vPw_oKCiH3X6',#42,$,$,(#898),#964); +#974= IFCPROPERTYSET('19G2kjMqT2bw6UTe26I2V$',#42,'Phasing',$,(#727)); +#976= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTu26I2V$',#42,$,$,(#898),#974); +#979= IFCPROPERTYSET('19G2kjMqT2bw6UTeA6I2V$',#42,'Structural',$,(#914,#915,#916)); +#984= IFCRELDEFINESBYPROPERTIES('19G2kjMqT2bw6UTuA6I2V$',#42,$,$,(#898),#979); +#987= IFCPROPERTYSET('19G2kjMqT2bw6UTek6I3JE',#42,'Construction',$,(#929)); +#990= IFCPROPERTYSET('19G2kjMqT2bw6UTes6I3JE',#42,'Dimensions',$,(#930,#931,#932)); +#995= IFCPROPERTYSET('19G2kjMqT2bw6UTeg6I3JE',#42,'Graphics',$,(#927,#928)); +#999= IFCPROPERTYSET('19G2kjMqT2bw6UTew6I3JE',#42,'Identity Data',$,(#740,#741,#742,#744,#745,#746,#933,#934)); +#1003= IFCPROPERTYSET('0wYiXNUp58QeDog$ZtpK0I',#42,'Other',$,(#922,#935)); +#1006= IFCAXIS2PLACEMENT3D(#6,$,$); +#1007= IFCLOCALPLACEMENT(#145,#1029); +#1008= IFCCARTESIANPOINT((240928.581159878,149778.983059267)); +#1010= IFCCARTESIANPOINT((240914.439024255,149793.12519489)); +#1012= IFCPOLYLINE((#1008,#1010)); +#1014= IFCGEOMETRICCURVESET((#1012)); +#1016= IFCCOLOURRGB($,0.,0.,0.); +#1017= IFCDRAUGHTINGPREDEFINEDCURVEFONT('continuous'); +#1018= IFCCURVESTYLE('Thin Lines',#1017,$,#1016,$); +#1019= IFCPRESENTATIONSTYLEASSIGNMENT((#1018)); +#1021= IFCSTYLEDITEM(#1014,(#1019),$); +#1024= IFCSHAPEREPRESENTATION(#104,'Annotation','Annotation2D',(#1014)); +#1026= IFCPRODUCTDEFINITIONSHAPE($,$,(#1024)); +#1029= IFCAXIS2PLACEMENT3D(#6,$,$); +#1030= IFCANNOTATION('1jkJR2yV94xeQKZO34YBI4',#42,$,$,$,#1007,#1026); +#1034= IFCCARTESIANPOINT((9914.49999983799,30485.5000000002,0.)); +#1036= IFCAXIS2PLACEMENT3D(#1034,$,$); +#1037= IFCLOCALPLACEMENT(#139,#1036); +#1038= IFCCARTESIANPOINT((54171.,0.)); +#1040= IFCPOLYLINE((#10,#1038)); +#1042= IFCSHAPEREPRESENTATION(#98,'Axis','Curve2D',(#1040)); +#1045= IFCCARTESIANPOINT((27085.5,3.41060513164848E-13)); +#1047= IFCAXIS2PLACEMENT2D(#1045,#26); +#1048= IFCRECTANGLEPROFILEDEF(.AREA.,$,#1047,54171.,213.000000000004); +#1049= IFCAXIS2PLACEMENT3D(#6,$,$); +#1050= IFCEXTRUDEDAREASOLID(#1048,#1049,#20,3000.); +#1051= IFCCOLOURRGB($,0.96078431372549,0.96078431372549,0.96078431372549); +#1052= IFCSURFACESTYLERENDERING(#1051,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#1053= IFCSURFACESTYLE('Dobbelfals Liggende Kledning - R\X2\00D8\X0\D',.BOTH.,(#1052)); +#1055= IFCPRESENTATIONSTYLEASSIGNMENT((#1053)); +#1057= IFCSTYLEDITEM(#1050,(#1055),$); +#1060= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1050)); +#1062= IFCPRODUCTDEFINITIONSHAPE($,$,(#1042,#1060)); +#1066= IFCWALLSTANDARDCASE('03NDr_iTb47OvHk1xabUui',#42,'Basic Wall:V10:4932686',$,'Basic Wall:V10:4929999',#1037,#1062,'4932686',.NOTDEFINED.); +#1069= IFCMATERIAL('Dobbelfals Liggende Kledning - R\X2\00D8\X0\D',$,$); +#1070= IFCPRESENTATIONSTYLEASSIGNMENT((#1053)); +#1072= IFCSTYLEDITEM($,(#1070),$); +#1074= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1072)); +#1076= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1074),#1069); +#1080= IFCMATERIAL('Luft',$,$); +#1081= IFCCOLOURRGB($,1.,1.,1.); +#1082= IFCSURFACESTYLERENDERING(#1081,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(0.),.NOTDEFINED.); +#1083= IFCSURFACESTYLE('Luft',.BOTH.,(#1082)); +#1085= IFCPRESENTATIONSTYLEASSIGNMENT((#1083)); +#1087= IFCSTYLEDITEM($,(#1085),$); +#1089= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1087)); +#1091= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1089),#1080); +#1095= IFCMATERIAL('Asfaltplate',$,$); +#1096= IFCCOLOURRGB($,0.0352941176470588,0.0352941176470588,0.0352941176470588); +#1097= IFCSURFACESTYLERENDERING(#1096,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#1098= IFCSURFACESTYLE('Asfaltplate',.BOTH.,(#1097)); +#1100= IFCPRESENTATIONSTYLEASSIGNMENT((#1098)); +#1102= IFCSTYLEDITEM($,(#1100),$); +#1104= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1102)); +#1106= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1104),#1095); +#1110= IFCMATERIAL('Stender/Isolasjon',$,$); +#1111= IFCCOLOURRGB($,0.6,0.6,0.6); +#1112= IFCSURFACESTYLERENDERING(#1111,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.); +#1113= IFCSURFACESTYLE('Stender/Isolasjon',.BOTH.,(#1112)); +#1115= IFCPRESENTATIONSTYLEASSIGNMENT((#1113)); +#1117= IFCSTYLEDITEM($,(#1115),$); +#1119= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1117)); +#1121= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1119),#1110); +#1125= IFCMATERIAL('Vegg - Gips',$,$); +#1126= IFCCOLOURRGB($,0.956862745098039,0.956862745098039,0.956862745098039); +#1127= IFCSURFACESTYLERENDERING(#1126,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(128.),.NOTDEFINED.); +#1128= IFCSURFACESTYLE('Vegg - Gips',.BOTH.,(#1127)); +#1130= IFCPRESENTATIONSTYLEASSIGNMENT((#1128)); +#1132= IFCSTYLEDITEM($,(#1130),$); +#1134= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1132)); +#1136= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1134),#1125); +#1140= IFCMATERIALLAYER(#1069,19.,$,$,$,$,$); +#1142= IFCMATERIALLAYER(#1080,23.,$,$,$,$,$); +#1143= IFCMATERIALLAYER(#1095,0.,$,$,$,$,$); +#1144= IFCMATERIALLAYER(#1110,150.,$,$,$,$,$); +#1145= IFCMATERIALLAYER(#1125,21.,$,$,$,$,$); +#1146= IFCMATERIALLAYERSET((#1140,#1142,#1143,#1144,#1145),'Basic Wall:V10',$); +#1153= IFCMATERIALLAYERSETUSAGE(#1146,.AXIS2.,.NEGATIVE.,106.5,$); +#1155= IFCWALLTYPE('2g96BiTO1FDP$QYgEYThRH',#42,'Basic Wall:V10',$,$,(#1239,#1243,#1249,#1252,#1256,#1259),$,'4929999',$,.NOTDEFINED.); +#1156= IFCPROPERTYSINGLEVALUE('Base Constraint',$,IFCLABEL('Level: PLAN 01'),$); +#1157= IFCPROPERTYSINGLEVALUE('Base Extension Distance',$,IFCLENGTHMEASURE(0.),$); +#1158= IFCPROPERTYSINGLEVALUE('Base is Attached',$,IFCBOOLEAN(.F.),$); +#1159= IFCPROPERTYSINGLEVALUE('Base Offset',$,IFCLENGTHMEASURE(0.),$); +#1160= IFCPROPERTYSINGLEVALUE('Location Line',$,IFCIDENTIFIER('Finish Face: Interior'),$); +#1161= IFCPROPERTYSINGLEVALUE('Related to Mass',$,IFCBOOLEAN(.F.),$); +#1162= IFCPROPERTYSINGLEVALUE('Room Bounding',$,IFCBOOLEAN(.T.),$); +#1163= IFCPROPERTYSINGLEVALUE('Top Extension Distance',$,IFCLENGTHMEASURE(0.),$); +#1164= IFCPROPERTYSINGLEVALUE('Top is Attached',$,IFCBOOLEAN(.F.),$); +#1165= IFCPROPERTYSINGLEVALUE('Top Offset',$,IFCLENGTHMEASURE(0.),$); +#1166= IFCPROPERTYSINGLEVALUE('Unconnected Height',$,IFCLENGTHMEASURE(3000.),$); +#1167= IFCPROPERTYSINGLEVALUE('Phase Created',$,IFCLABEL('Existing'),$); +#1168= IFCPROPERTYSINGLEVALUE('Enable Analytical Model',$,IFCBOOLEAN(.F.),$); +#1169= IFCPROPERTYSINGLEVALUE('Structural',$,IFCBOOLEAN(.F.),$); +#1170= IFCPROPERTYSINGLEVALUE('Structural Usage',$,IFCIDENTIFIER('Non-bearing'),$); +#1171= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(155.07025),$); +#1172= IFCPROPERTYSINGLEVALUE('Length',$,IFCLENGTHMEASURE(54171.),$); +#1173= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(33.0299632499999),$); +#1174= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Walls'),$); +#1175= IFCPROPERTYSINGLEVALUE('Family',$,IFCLABEL('Basic Wall: V10'),$); +#1176= IFCPROPERTYSINGLEVALUE('Family and Type',$,IFCLABEL('Basic Wall: V10'),$); +#1177= IFCPROPERTYSINGLEVALUE('Type',$,IFCLABEL('Basic Wall: V10'),$); +#1178= IFCPROPERTYSINGLEVALUE('Type Id',$,IFCLABEL('Basic Wall: V10'),$); +#1179= IFCPROPERTYSINGLEVALUE('Absorptance',$,IFCREAL(0.1),$); +#1180= IFCPROPERTYSINGLEVALUE('Roughness',$,IFCINTEGER(1),$); +#1181= IFCPROPERTYSINGLEVALUE('Structural Material',$,IFCLABEL('Stender/Isolasjon'),$); +#1182= IFCPROPERTYSINGLEVALUE('Coarse Scale Fill Color',$,IFCINTEGER(0),$); +#1183= IFCPROPERTYSINGLEVALUE('Function',$,IFCIDENTIFIER('Exterior'),$); +#1184= IFCPROPERTYSINGLEVALUE('Width',$,IFCLENGTHMEASURE(213.),$); +#1185= IFCPROPERTYSINGLEVALUE('Wrapping at Ends',$,IFCIDENTIFIER('None'),$); +#1186= IFCPROPERTYSINGLEVALUE('Wrapping at Inserts',$,IFCIDENTIFIER('Do not wrap'),$); +#1187= IFCPROPERTYSINGLEVALUE('Type Comments',$,IFCTEXT('1'),$); +#1188= IFCPROPERTYSINGLEVALUE('Type Name',$,IFCTEXT('V10'),$); +#1189= IFCPROPERTYSINGLEVALUE('Family Name',$,IFCTEXT('Basic Wall'),$); +#1190= IFCPROPERTYSET('03NDr_iTb47OvHlWhabUui',#42,'Constraints',$,(#1156,#1157,#1158,#1159,#1160,#1161,#1162,#1163,#1164,#1165,#1166)); +#1203= IFCRELDEFINESBYPROPERTIES('03NDr_iTb47OvHlmhabUui',#42,$,$,(#1066),#1190); +#1207= IFCPROPERTYSET('03NDr_iTb47OvHlXpabUui',#42,'Dimensions',$,(#1171,#1172,#1173)); +#1212= IFCRELDEFINESBYPROPERTIES('03NDr_iTb47OvHlnpabUui',#42,$,$,(#1066),#1207); +#1215= IFCPROPERTYSET('35OoXI64v27fLUuLKme2ma',#42,'Other',$,(#1174,#1175,#1176,#1177,#1178)); +#1222= IFCRELDEFINESBYPROPERTIES('3cyXhmDsPA8RRkkeG1JFpJ',#42,$,$,(#1066),#1215); +#1225= IFCPROPERTYSET('03NDr_iTb47OvHlX7abUui',#42,'Phasing',$,(#1167)); +#1228= IFCRELDEFINESBYPROPERTIES('03NDr_iTb47OvHln7abUui',#42,$,$,(#1066),#1225); +#1231= IFCPROPERTYSET('03NDr_iTb47OvHlXFabUui',#42,'Structural',$,(#1168,#1169,#1170)); +#1236= IFCRELDEFINESBYPROPERTIES('03NDr_iTb47OvHlnFabUui',#42,$,$,(#1066),#1231); +#1239= IFCPROPERTYSET('2g96BiTO1FDP$QZFwYThRH',#42,'Analytical Properties',$,(#1179,#1180)); +#1243= IFCPROPERTYSET('2g96BiTO1FDP$QZAUYThRH',#42,'Construction',$,(#1183,#1184,#1185,#1186)); +#1249= IFCPROPERTYSET('2g96BiTO1FDP$QZAQYThRH',#42,'Graphics',$,(#1182)); +#1252= IFCPROPERTYSET('2g96BiTO1FDP$QZAAYThRH',#42,'Identity Data',$,(#740,#741,#1187,#1188)); +#1256= IFCPROPERTYSET('2g96BiTO1FDP$QZAMYThRH',#42,'Materials and Finishes',$,(#1181)); +#1259= IFCPROPERTYSET('2NUKjTKavCBgnhbHKmcMf9',#42,'Other',$,(#1174,#1189)); +#1269= IFCCARTESIANPOINT((-865.,-450.)); +#1271= IFCCARTESIANPOINT((865.,-450.)); +#1273= IFCCARTESIANPOINT((865.,450.)); +#1275= IFCCARTESIANPOINT((-865.,450.)); +#1277= IFCPOLYLINE((#1269,#1271,#1273,#1275,#1269)); +#1279= IFCCARTESIANPOINT((-325.,-400.)); +#1281= IFCCARTESIANPOINT((-815.,-400.)); +#1283= IFCCARTESIANPOINT((-815.,400.)); +#1285= IFCCARTESIANPOINT((-325.,400.)); +#1287= IFCPOLYLINE((#1279,#1281,#1283,#1285,#1279)); +#1289= IFCCARTESIANPOINT((815.,400.)); +#1291= IFCCARTESIANPOINT((815.,-400.)); +#1293= IFCCARTESIANPOINT((325.,-400.)); +#1295= IFCCARTESIANPOINT((325.,400.)); +#1297= IFCPOLYLINE((#1289,#1291,#1293,#1295,#1289)); +#1299= IFCCARTESIANPOINT((-275.,-400.)); +#1301= IFCCARTESIANPOINT((-275.,400.)); +#1303= IFCCARTESIANPOINT((275.,400.)); +#1305= IFCCARTESIANPOINT((275.,-400.)); +#1307= IFCPOLYLINE((#1299,#1301,#1303,#1305,#1299)); +#1309= IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,'Vindu 3 felt med 3 \X2\00E5\X0\pninger',#1277,(#1287,#1297,#1307)); +#1311= IFCCARTESIANPOINT((959.796538590871,153.,460.)); +#1313= IFCAXIS2PLACEMENT3D(#1311,#18,#14); +#1314= IFCEXTRUDEDAREASOLID(#1309,#1313,#20,99.999999999996); +#1315= IFCCARTESIANPOINT((-865.,-450.)); +#1317= IFCCARTESIANPOINT((865.,-450.)); +#1319= IFCCARTESIANPOINT((865.,450.)); +#1321= IFCCARTESIANPOINT((-865.,450.)); +#1323= IFCPOLYLINE((#1315,#1317,#1319,#1321,#1315)); +#1325= IFCCARTESIANPOINT((-845.,-430.)); +#1327= IFCCARTESIANPOINT((-845.,430.)); +#1329= IFCCARTESIANPOINT((845.,430.)); +#1331= IFCCARTESIANPOINT((845.,-430.)); +#1333= IFCPOLYLINE((#1325,#1327,#1329,#1331,#1325)); +#1335= IFCARBITRARYPROFILEDEFWITHVOIDS(.AREA.,'Vindu 3 felt med 3 \X2\00E5\X0\pninger',#1323,(#1333)); +#1337= IFCCARTESIANPOINT((959.796538590869,53.,460.)); +#1339= IFCAXIS2PLACEMENT3D(#1337,#18,#12); +#1340= IFCEXTRUDEDAREASOLID(#1335,#1339,#20,93.000000000008); +#1341= IFCCARTESIANPOINT((0.,1.77635683940025E-15)); +#1343= IFCAXIS2PLACEMENT2D(#1341,#24); +#1344= IFCRECTANGLEPROFILEDEF(.AREA.,'Vindu 3 felt med 3 \X2\00E5\X0\pninger',#1343,550.000000000005,10.); +#1345= IFCCARTESIANPOINT((959.796538590869,128.,60.)); +#1347= IFCAXIS2PLACEMENT3D(#1345,#20,#14); +#1348= IFCEXTRUDEDAREASOLID(#1344,#1347,#20,799.999999999981); +#1349= IFCCOLOURRGB($,0.956862745098039,0.956862745098039,0.956862745098039); +#1350= IFCSURFACESTYLERENDERING(#1349,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(128.),.NOTDEFINED.); +#1351= IFCSURFACESTYLE('Hvit',.BOTH.,(#1350)); +#1353= IFCPRESENTATIONSTYLEASSIGNMENT((#1351)); +#1355= IFCSTYLEDITEM(#1314,(#1353),$); +#1358= IFCSTYLEDITEM(#1340,(#1353),$); +#1361= IFCCOLOURRGB($,0.854901960784314,0.890196078431373,0.87843137254902); +#1362= IFCSURFACESTYLERENDERING(#1361,0.85,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(12.),.NOTDEFINED.); +#1363= IFCSURFACESTYLE('Glassplater',.BOTH.,(#1362)); +#1365= IFCPRESENTATIONSTYLEASSIGNMENT((#1363)); +#1367= IFCSTYLEDITEM(#1348,(#1365),$); +#1370= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1314,#1340,#1348)); +#1372= IFCCARTESIANPOINT((1749.32448009269,297.459222269011)); +#1374= IFCCARTESIANPOINT((1774.79653859088,153.)); +#1376= IFCPOLYLINE((#1372,#1374)); +#1378= IFCCARTESIANPOINT((609.324480092671,297.45922226901)); +#1380= IFCCARTESIANPOINT((634.796538590859,153.)); +#1382= IFCPOLYLINE((#1378,#1380)); +#1384= IFCCARTESIANPOINT((609.324480092671,297.45922226901)); +#1386= IFCCARTESIANPOINT((144.79653859087,153.)); +#1388= IFCPOLYLINE((#1384,#1386)); +#1390= IFCCARTESIANPOINT((1749.32448009269,297.459222269011)); +#1392= IFCCARTESIANPOINT((1284.79653859088,153.)); +#1394= IFCPOLYLINE((#1390,#1392)); +#1396= IFCGEOMETRICSET((#1376,#1382,#1388,#1394)); +#1398= IFCSHAPEREPRESENTATION(#104,'FootPrint','GeometricSet',(#1396)); +#1400= IFCAXIS2PLACEMENT3D(#6,$,$); +#1401= IFCREPRESENTATIONMAP(#1400,#1370); +#1403= IFCREPRESENTATIONMAP(#1400,#1398); +#1405= IFCWINDOWLININGPROPERTIES('2s384mGt93XQ6GAKtxEBEF',#42,'Eks V1:Vindu 3 felt med 3 \X2\00E5\X0\pninger:5304233',$,$,$,$,$,$,$,$,$,$,$,$,$); +#1406= IFCWINDOWTYPE('2BB$9YoXb9ofcxEmoUuBl7',#42,'Vindu 3 felt med 3 \X2\00E5\X0\pninger',$,$,(#1405,#1535,#1538,#1541,#1545,#1554,#1560,#1565),(#1401,#1403),'6053107',$,.WINDOW.,.NOTDEFINED.,.F.,$); +#1410= IFCMATERIAL('Hvit',$,$); +#1411= IFCPRESENTATIONSTYLEASSIGNMENT((#1351)); +#1413= IFCSTYLEDITEM($,(#1411),$); +#1415= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1413)); +#1417= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1415),#1410); +#1421= IFCMATERIAL('Glassplater',$,$); +#1422= IFCPRESENTATIONSTYLEASSIGNMENT((#1363)); +#1424= IFCSTYLEDITEM($,(#1422),$); +#1426= IFCSTYLEDREPRESENTATION(#95,'Style','Material',(#1424)); +#1428= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#1426),#1421); +#1432= IFCMATERIALLIST((#1410,#1421)); +#1434= IFCMAPPEDITEM(#1401,#684); +#1436= IFCSHAPEREPRESENTATION(#100,'Body','MappedRepresentation',(#1434)); +#1438= IFCMAPPEDITEM(#1403,#684); +#1440= IFCSHAPEREPRESENTATION(#104,'FootPrint','MappedRepresentation',(#1438)); +#1442= IFCPRODUCTDEFINITIONSHAPE($,$,(#1436,#1440)); +#1446= IFCCARTESIANPOINT((61178.1361954652,30419.,1200.)); +#1448= IFCAXIS2PLACEMENT3D(#1446,$,$); +#2170= IFCLOCALPLACEMENT(#2154,#2169); +#1450= IFCWINDOW('1PTz52_o9DlAOe37wu2tDU',#42,'Eks V1:Vindu 3 felt med 3 \X2\00E5\X0\pninger:5304233',$,'Vindu 3 felt med 3 \X2\00E5\X0\pninger',#2170,#1442,'5304233',920.000000000016,1750.,.WINDOW.,.NOTDEFINED.,$); +#1453= IFCMATERIALLIST((#1410,#1421)); +#1455= IFCPROPERTYSINGLEVALUE('Sill Height',$,IFCLENGTHMEASURE(1200.),$); +#1456= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(2.02784000000005),$); +#1457= IFCPROPERTYSINGLEVALUE('Height',$,IFCLENGTHMEASURE(920.),$); +#1458= IFCPROPERTYSINGLEVALUE('Innsetting',$,IFCLENGTHMEASURE(20.),$); +#1459= IFCPROPERTYSINGLEVALUE('Spalte',$,IFCLENGTHMEASURE(10.),$); +#1460= IFCPROPERTYSINGLEVALUE('Veggtykkelse',$,IFCLENGTHMEASURE(213.),$); +#1461= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.0473348000000038),$); +#1462= IFCPROPERTYSINGLEVALUE('Width',$,IFCLENGTHMEASURE(1750.),$); +#1463= IFCPROPERTYSINGLEVALUE('Mark',$,IFCTEXT('32'),$); +#1464= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Windows'),$); +#1465= IFCPROPERTYSINGLEVALUE('Family',$,IFCLABEL('Eks V1: Vindu 3 felt med 3 \X2\00E5\X0\pninger'),$); +#1466= IFCPROPERTYSINGLEVALUE('Family and Type',$,IFCLABEL('Eks V1: Vindu 3 felt med 3 \X2\00E5\X0\pninger'),$); +#1467= IFCPROPERTYSINGLEVALUE('Head Height',$,IFCLENGTHMEASURE(2120.),$); +#1468= IFCPROPERTYSINGLEVALUE('Host Id',$,IFCLABEL('Basic Wall: V10'),$); +#1469= IFCPROPERTYSINGLEVALUE('Type',$,IFCLABEL('Eks V1: Vindu 3 felt med 3 \X2\00E5\X0\pninger'),$); +#1470= IFCPROPERTYSINGLEVALUE('Type Id',$,IFCLABEL('Eks V1: Vindu 3 felt med 3 \X2\00E5\X0\pninger'),$); +#1471= IFCPROPERTYSINGLEVALUE('Analytic Construction',$,IFCTEXT(''),$); +#1472= IFCPROPERTYSINGLEVALUE('Total glass area',$,IFCAREAMEASURE(0.7352),$); +#1473= IFCPROPERTYSINGLEVALUE('Glassmateriale',$,IFCLABEL('Glassplater'),$); +#1474= IFCPROPERTYSINGLEVALUE('Karmmateriale',$,IFCLABEL('Hvit'),$); +#1475= IFCPROPERTYSINGLEVALUE('Utforingsmateriale',$,IFCLABEL('Hvit'),$); +#1476= IFCPROPERTYSINGLEVALUE('Utforing',$,IFCBOOLEAN(.T.),$); +#1477= IFCPROPERTYSINGLEVALUE('Wall Closure',$,IFCIDENTIFIER('By host'),$); +#1478= IFCPROPERTYSINGLEVALUE('Bredde \X2\00E5\X0\pningsfelt',$,IFCLENGTHMEASURE(590.),$); +#1479= IFCPROPERTYSINGLEVALUE('Karmbredde',$,IFCLENGTHMEASURE(50.),$); +#1480= IFCPROPERTYSINGLEVALUE('Karmdybde',$,IFCLENGTHMEASURE(100.),$); +#1481= IFCPROPERTYSINGLEVALUE('Rammebredde',$,IFCLENGTHMEASURE(40.),$); +#1482= IFCPROPERTYSINGLEVALUE('Rough Height',$,IFCLENGTHMEASURE(900.),$); +#1483= IFCPROPERTYSINGLEVALUE('Rough Width',$,IFCLENGTHMEASURE(1730.),$); +#1484= IFCPROPERTYSINGLEVALUE('Utforingstykkelse',$,IFCLENGTHMEASURE(20.),$); +#1485= IFCPROPERTYSINGLEVALUE('Type Mark',$,IFCTEXT('EKS'),$); +#1486= IFCPROPERTYSINGLEVALUE('Type Name',$,IFCTEXT('Vindu 3 felt med 3 \X2\00E5\X0\pninger'),$); +#1487= IFCPROPERTYSINGLEVALUE('URL',$,IFCTEXT(''),$); +#1488= IFCPROPERTYSINGLEVALUE('WindowBasalOpening',$,IFCTEXT('Unspecified'),$); +#1489= IFCPROPERTYSINGLEVALUE('Default Sill Height',$,IFCLENGTHMEASURE(900.),$); +#1490= IFCPROPERTYSINGLEVALUE('Family Name',$,IFCTEXT('Eks V1'),$); +#1491= IFCPROPERTYSINGLEVALUE('M_Height',$,IFCINTEGER(9),$); +#1492= IFCPROPERTYSINGLEVALUE('M_Width',$,IFCINTEGER(17),$); +#1493= IFCPROPERTYSET('1PTz52_o9DlAOe2cgu2tDU',#42,'Constraints',$,(#724,#1455)); +#1496= IFCRELDEFINESBYPROPERTIES('1PTz52_o9DlAOe2sgu2tDU',#42,$,$,(#1450),#1493); +#1500= IFCPROPERTYSET('1PTz52_o9DlAOe2dou2tDU',#42,'Dimensions',$,(#1456,#1457,#1458,#1459,#1460,#1461,#1462)); +#1509= IFCRELDEFINESBYPROPERTIES('1PTz52_o9DlAOe2tou2tDU',#42,$,$,(#1450),#1500); +#1512= IFCPROPERTYSET('1PTz52_o9DlAOe2d_u2tDU',#42,'Identity Data',$,(#1463)); +#1515= IFCRELDEFINESBYPROPERTIES('1PTz52_o9DlAOe2t_u2tDU',#42,$,$,(#1450),#1512); +#1518= IFCPROPERTYSET('0OD0h_ZWTC9w4ma4waZMTk',#42,'Other',$,(#1464,#1465,#1466,#1467,#1468,#1469,#1470)); +#1527= IFCRELDEFINESBYPROPERTIES('1W7re08Ab2whlzYuJMxO6o',#42,$,$,(#1450),#1518); +#1530= IFCPROPERTYSET('1PTz52_o9DlAOe2d6u2tDU',#42,'Phasing',$,(#1167)); +#1532= IFCRELDEFINESBYPROPERTIES('1PTz52_o9DlAOe2t6u2tDU',#42,$,$,(#1450),#1530); +#1535= IFCPROPERTYSET('2BB$9YoXb9ofcxFIUUu8yJ',#42,'Analysis Results',$,(#1472)); +#1538= IFCPROPERTYSET('2BB$9YoXb9ofcxFKIUu8yJ',#42,'Analytical Properties',$,(#1471)); +#1541= IFCPROPERTYSET('2BB$9YoXb9ofcxFHsUu8yJ',#42,'Construction',$,(#1476,#1477)); +#1545= IFCPROPERTYSET('2BB$9YoXb9ofcxFHkUu8yJ',#42,'Dimensions',$,(#1478,#1479,#1480,#1481,#1482,#1483,#1484)); +#1554= IFCPROPERTYSET('2BB$9YoXb9ofcxFHYUu8yJ',#42,'Identity Data',$,(#740,#741,#742,#744,#745,#746,#747,#1485,#1486,#1487,#1488)); +#1560= IFCPROPERTYSET('2BB$9YoXb9ofcxFH_Uu8yJ',#42,'Materials and Finishes',$,(#1473,#1474,#1475)); +#1565= IFCPROPERTYSET('0F3yDlIkfCzwJW1hy5mnqw',#42,'Other',$,(#1464,#1489,#1490,#1491,#1492)); +#1579= IFCCARTESIANPOINT((41181.,30485.5000000001,1050.)); +#1581= IFCAXIS2PLACEMENT3D(#1579,$,$); +#1582= IFCLOCALPLACEMENT(#139,#1581); +#1583= IFCCARTESIANPOINT((1050.,-0.)); +#1585= IFCPOLYLINE((#10,#1583)); +#1587= IFCSHAPEREPRESENTATION(#98,'Axis','Curve2D',(#1585)); +#1589= IFCCARTESIANPOINT((0.,0.)); +#1591= IFCAXIS2PLACEMENT2D(#1589,#24); +#1592= IFCRECTANGLEPROFILEDEF(.AREA.,'V10',#1591,1049.99999999999,212.999999999999); +#1593= IFCCARTESIANPOINT((525.,0.,0.)); +#1595= IFCAXIS2PLACEMENT3D(#1593,$,$); +#1596= IFCEXTRUDEDAREASOLID(#1592,#1595,#20,955.000000000028); +#1597= IFCSTYLEDITEM(#1596,(#1055),$); +#1600= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1596)); +#1602= IFCPRODUCTDEFINITIONSHAPE($,$,(#1587,#1600)); +#1606= IFCWALLSTANDARDCASE('3UltsdvPH0afI77DdCyC7z',#42,'Basic Wall:V10:5626624',$,'Basic Wall:V10:4929999',#1582,#1602,'5626624',.NOTDEFINED.); +#1609= IFCMATERIALLAYERSETUSAGE(#1146,.AXIS2.,.NEGATIVE.,106.5,$); +#1610= IFCPROPERTYSINGLEVALUE('Location Line',$,IFCIDENTIFIER('Wall Centerline'),$); +#1611= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(1.00275000000003),$); +#1612= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.213585750000004),$); +#1613= IFCPROPERTYSET('3UltsdvPH0afI76itCyC7z',#42,'Constraints',$,(#1157,#1161,#1163,#1610)); +#1616= IFCRELDEFINESBYPROPERTIES('3UltsdvPH0afI76ytCyC7z',#42,$,$,(#1606),#1613); +#1620= IFCPROPERTYSET('3UltsdvPH0afI76jlCyC7z',#42,'Dimensions',$,(#1611,#1612)); +#1624= IFCRELDEFINESBYPROPERTIES('3UltsdvPH0afI76zlCyC7z',#42,$,$,(#1606),#1620); +#1627= IFCPROPERTYSET('3$$ekGHX90XuxsyUbzpLxd',#42,'Other',$,(#1174,#1175,#1176,#1177,#1178)); +#1629= IFCRELDEFINESBYPROPERTIES('3aT2$J5_jCqf3wnAUTstKb',#42,$,$,(#1606),#1627); +#1632= IFCPROPERTYSET('3UltsdvPH0afI76jJCyC7z',#42,'Structural',$,(#1168,#1169,#1170)); +#1634= IFCRELDEFINESBYPROPERTIES('3UltsdvPH0afI76zJCyC7z',#42,$,$,(#1606),#1632); +#1637= IFCCARTESIANPOINT((18125.,30485.5000000002,1050.)); +#1639= IFCAXIS2PLACEMENT3D(#1637,$,$); +#1640= IFCLOCALPLACEMENT(#139,#1639); +#1641= IFCCARTESIANPOINT((1750.,0.)); +#1643= IFCPOLYLINE((#10,#1641)); +#1645= IFCSHAPEREPRESENTATION(#98,'Axis','Curve2D',(#1643)); +#1647= IFCCARTESIANPOINT((-2.21689333557151E-12,0.)); +#1649= IFCAXIS2PLACEMENT2D(#1647,#24); +#1650= IFCRECTANGLEPROFILEDEF(.AREA.,'V10',#1649,1750.,212.999999999999); +#1651= IFCCARTESIANPOINT((875.,0.,0.)); +#1653= IFCAXIS2PLACEMENT3D(#1651,#20,#14); +#1654= IFCEXTRUDEDAREASOLID(#1650,#1653,#20,920.000000000016); +#1655= IFCSTYLEDITEM(#1654,(#1055),$); +#1658= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1654)); +#1660= IFCPRODUCTDEFINITIONSHAPE($,$,(#1645,#1658)); +#1664= IFCWALLSTANDARDCASE('3n3el7tsPBORtUY9oVoMDi',#42,'Basic Wall:V10:5839377',$,'Basic Wall:V10:4929999',#1640,#1660,'5839377',.NOTDEFINED.); +#1667= IFCMATERIALLAYERSETUSAGE(#1146,.AXIS2.,.NEGATIVE.,106.5,$); +#1668= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(1.61000000000002),$); +#1669= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.342930000000004),$); +#1670= IFCPROPERTYSET('3n3el7tsPBORtUZeYVoMDi',#42,'Constraints',$,(#1157,#1161,#1163,#1610)); +#1672= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZuYVoMDi',#42,$,$,(#1664),#1670); +#1676= IFCPROPERTYSET('3n3el7tsPBORtUZfwVoMDi',#42,'Dimensions',$,(#1668,#1669)); +#1680= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZvwVoMDi',#42,$,$,(#1664),#1676); +#1683= IFCPROPERTYSET('3jSro$XJ943vTpKXds2soE',#42,'Other',$,(#1174,#1175,#1176,#1177,#1178)); +#1685= IFCRELDEFINESBYPROPERTIES('1w0L6nC6j6iha$8sZIQ7fE',#42,$,$,(#1664),#1683); +#1688= IFCPROPERTYSET('3n3el7tsPBORtUZf6VoMDi',#42,'Structural',$,(#1168,#1169,#1170)); +#1690= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZv6VoMDi',#42,$,$,(#1664),#1688); +#1693= IFCCARTESIANPOINT((14525.,30485.5000000002,1050.)); +#1695= IFCAXIS2PLACEMENT3D(#1693,$,$); +#1696= IFCLOCALPLACEMENT(#139,#1695); +#1697= IFCCARTESIANPOINT((1750.,-0.)); +#1699= IFCPOLYLINE((#10,#1697)); +#1701= IFCSHAPEREPRESENTATION(#98,'Axis','Curve2D',(#1699)); +#1703= IFCCARTESIANPOINT((0.,2.16715534406831E-12)); +#1705= IFCAXIS2PLACEMENT2D(#1703,#24); +#1706= IFCRECTANGLEPROFILEDEF(.AREA.,'V10',#1705,1750.,212.999999999999); +#1707= IFCCARTESIANPOINT((875.,0.,0.)); +#1709= IFCAXIS2PLACEMENT3D(#1707,#20,#14); +#1710= IFCEXTRUDEDAREASOLID(#1706,#1709,#20,920.000000000016); +#1711= IFCSTYLEDITEM(#1710,(#1055),$); +#1714= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1710)); +#1716= IFCPRODUCTDEFINITIONSHAPE($,$,(#1701,#1714)); +#1720= IFCWALLSTANDARDCASE('3n3el7tsPBORtUY9oVoMDl',#42,'Basic Wall:V10:5839378',$,'Basic Wall:V10:4929999',#1696,#1716,'5839378',.NOTDEFINED.); +#1723= IFCMATERIALLAYERSETUSAGE(#1146,.AXIS2.,.NEGATIVE.,106.5,$); +#1724= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(1.61000000000003),$); +#1725= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.342930000000004),$); +#1726= IFCPROPERTYSET('3n3el7tsPBORtUZeYVoMDl',#42,'Constraints',$,(#1157,#1161,#1163,#1610)); +#1728= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZuYVoMDl',#42,$,$,(#1720),#1726); +#1732= IFCPROPERTYSET('3n3el7tsPBORtUZfwVoMDl',#42,'Dimensions',$,(#1724,#1725)); +#1736= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZvwVoMDl',#42,$,$,(#1720),#1732); +#1739= IFCPROPERTYSET('39krQ544P8_OprvvIRSUar',#42,'Other',$,(#1174,#1175,#1176,#1177,#1178)); +#1741= IFCRELDEFINESBYPROPERTIES('2Ov7dVxmz1dOGNawy3WYsC',#42,$,$,(#1720),#1739); +#1744= IFCPROPERTYSET('3n3el7tsPBORtUZf6VoMDl',#42,'Structural',$,(#1168,#1169,#1170)); +#1746= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZv6VoMDl',#42,$,$,(#1720),#1744); +#1749= IFCCARTESIANPOINT((10925.,30485.5000000002,1050.)); +#1751= IFCAXIS2PLACEMENT3D(#1749,$,$); +#1752= IFCLOCALPLACEMENT(#139,#1751); +#1753= IFCCARTESIANPOINT((1750.,0.)); +#1755= IFCPOLYLINE((#10,#1753)); +#1757= IFCSHAPEREPRESENTATION(#98,'Axis','Curve2D',(#1755)); +#1759= IFCCARTESIANPOINT((0.,0.)); +#1761= IFCAXIS2PLACEMENT2D(#1759,#24); +#1762= IFCRECTANGLEPROFILEDEF(.AREA.,'V10',#1761,1750.,212.999999999999); +#1763= IFCCARTESIANPOINT((875.,0.,0.)); +#1765= IFCAXIS2PLACEMENT3D(#1763,#20,#14); +#1766= IFCEXTRUDEDAREASOLID(#1762,#1765,#20,920.000000000016); +#1767= IFCSTYLEDITEM(#1766,(#1055),$); +#1770= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#1766)); +#1772= IFCPRODUCTDEFINITIONSHAPE($,$,(#1757,#1770)); +#1776= IFCWALLSTANDARDCASE('3n3el7tsPBORtUY9oVoMDk',#42,'Basic Wall:V10:5839379',$,'Basic Wall:V10:4929999',#1752,#1772,'5839379',.NOTDEFINED.); +#1779= IFCMATERIALLAYERSETUSAGE(#1146,.AXIS2.,.NEGATIVE.,106.5,$); +#1780= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(1.61000000000002),$); +#1781= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(0.342930000000004),$); +#1782= IFCPROPERTYSET('3n3el7tsPBORtUZeYVoMDk',#42,'Constraints',$,(#1157,#1161,#1163,#1610)); +#1784= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZuYVoMDk',#42,$,$,(#1776),#1782); +#1788= IFCPROPERTYSET('3n3el7tsPBORtUZfwVoMDk',#42,'Dimensions',$,(#1780,#1781)); +#1792= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZvwVoMDk',#42,$,$,(#1776),#1788); +#1795= IFCPROPERTYSET('2aiBhn_mH4LAX$O4Mvq2Pe',#42,'Other',$,(#1174,#1175,#1176,#1177,#1178)); +#1797= IFCRELDEFINESBYPROPERTIES('21L6h0R5T3yRZPLjGBWChp',#42,$,$,(#1776),#1795); +#1800= IFCPROPERTYSET('3n3el7tsPBORtUZf6VoMDk',#42,'Structural',$,(#1168,#1169,#1170)); +#1802= IFCRELDEFINESBYPROPERTIES('3n3el7tsPBORtUZv6VoMDk',#42,$,$,(#1776),#1800); +#1805= IFCTEXTSTYLEFONTMODEL('Text Font',('Arial Narrow'),$,$,$,IFCPOSITIVELENGTHMEASURE(250.)); +#1807= IFCCOLOURRGB($,0.,0.,0.); +#1808= IFCTEXTSTYLEFORDEFINEDFONT(#1807,$); +#1809= IFCTEXTSTYLE('2.5mm Arial Narrow',#1808,$,#1805,$); +#1810= IFCPRESENTATIONSTYLEASSIGNMENT((#1809)); +#1812= IFCAXIS2PLACEMENT3D(#6,$,$); +#1813= IFCLOCALPLACEMENT(#145,#1812); +#1814= IFCCARTESIANPOINT((20035.1896219398,22141.9509375934,0.)); +#1816= IFCAXIS2PLACEMENT3D(#1814,$,$); +#1817= IFCPLANAREXTENT(2925.,801.587301587301); +#1818= IFCTEXTLITERALWITHEXTENT('SPILLBAKKE H=50MM\X\0D\X\0ATILPASSES ',#1816,.LEFT.,#1817,'top-left'); +#1819= IFCSTYLEDITEM(#1818,(#1810),$); +#1822= IFCSHAPEREPRESENTATION(#104,'Annotation','Annotation2D',(#1818)); +#1824= IFCPRODUCTDEFINITIONSHAPE($,$,(#1822)); +#1827= IFCANNOTATION('11bZi6bUHFtOf1eiw_jjuT',#42,$,$,$,#1813,#1824); +#1830= IFCAXIS2PLACEMENT3D(#6,$,$); +#1831= IFCLOCALPLACEMENT(#145,#1830); +#1832= IFCCARTESIANPOINT((28028.0779111512,18894.0915743089,0.)); +#1834= IFCAXIS2PLACEMENT3D(#1832,$,$); +#1835= IFCPLANAREXTENT(3080.,801.587301587301); +#1836= IFCTEXTLITERALWITHEXTENT('SPILLBAKKE H=100MM\X\0D\X\0ATILPASSES ',#1834,.LEFT.,#1835,'top-left'); +#1837= IFCSTYLEDITEM(#1836,(#1810),$); +#1840= IFCSHAPEREPRESENTATION(#104,'Annotation','Annotation2D',(#1836)); +#1842= IFCPRODUCTDEFINITIONSHAPE($,$,(#1840)); +#1845= IFCANNOTATION('2oJ8CMMon7WQXfpAJDJOgH',#42,$,$,$,#1831,#1842); +#1848= IFCCARTESIANPOINT((114502766.318516,1185944009.,0.)); +#1850= IFCDIRECTION((0.995788774458495,0.0916772417912352,0.)); +#1852= IFCAXIS2PLACEMENT3D(#1848,#20,#1850); +#1853= IFCLOCALPLACEMENT($,#1852); +#1854= IFCSITE('3o91zj$Gr6cQ_i1EP5O_03',#42,'0214 41 1 00',$,'',#1853,$,'14323',.ELEMENT.,(59,39,52,987060),(10,47,40,726547),62050.,'0214 41 1 00',$); +#1858= IFCPROPERTYSINGLEVALUE('Author',$,IFCTEXT(''),$); +#1859= IFCPROPERTYSINGLEVALUE('Building Name',$,IFCTEXT('091'),$); +#1860= IFCPROPERTYSINGLEVALUE('CQIncludeDoorSwing',$,IFCBOOLEAN(.F.),$); +#1861= IFCPROPERTYSINGLEVALUE('CQIncludeRoomNumber',$,IFCBOOLEAN(.F.),$); +#1862= IFCPROPERTYSINGLEVALUE('Organization Description',$,IFCTEXT('A - Arkitekt'),$); +#1863= IFCPROPERTYSINGLEVALUE('Organization Name',$,IFCTEXT('PG Campus \X2\00C5\X0\s'),$); +#1864= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Project Information'),$); +#1865= IFCPROPERTYSINGLEVALUE('Client Name',$,IFCTEXT('Statsbygg'),$); +#1866= IFCPROPERTYSINGLEVALUE('CQDoorSwingCodes',$,IFCTEXT('Left=L;Right=R;notMirrored =;mirrored ='),$); +#1867= IFCPROPERTYSINGLEVALUE('CQIncludeTemporaryDoors',$,IFCBOOLEAN(.F.),$); +#1868= IFCPROPERTYSINGLEVALUE('CQPhaseFilter',$,IFCTEXT('Existing:True;New Construction:True;Temporary:True;'),$); +#1869= IFCPROPERTYSINGLEVALUE('Project Address',$,IFCTEXT('Forprosjekt'),$); +#1870= IFCPROPERTYSINGLEVALUE('Project Issue Date',$,IFCTEXT('SB_14323_03_ARK_091'),$); +#1871= IFCPROPERTYSINGLEVALUE('Project Name',$,IFCTEXT('14323'),$); +#1872= IFCPROPERTYSINGLEVALUE('Project Number',$,IFCTEXT('12370'),$); +#1873= IFCPROPERTYSINGLEVALUE('Project Status',$,IFCTEXT('02'),$); +#1874= IFCPROPERTYSET('27PCKGLxT4mxtV86o6mgBW',#42,'Identity Data',$,(#1858,#1859,#1860,#1861,#1862,#1863)); +#1882= IFCRELDEFINESBYPROPERTIES('27PCKGLxT4mxtV8Mo6mgBW',#42,$,$,(#1854),#1874); +#1886= IFCPROPERTYSET('3AcspaXOj4mxnskMsaPI1b',#42,'Other',$,(#1864,#1865,#1866,#1867,#1868,#1869,#1870,#1871,#1872,#1873)); +#1902= IFCPROPERTYSINGLEVALUE('Elevation',$,IFCLENGTHMEASURE(0.),$); +#1903= IFCPROPERTYSINGLEVALUE('Computation Height',$,IFCLENGTHMEASURE(1200.),$); +#1904= IFCPROPERTYSINGLEVALUE('Building Story',$,IFCBOOLEAN(.T.),$); +#1905= IFCPROPERTYSINGLEVALUE('Name',$,IFCTEXT('PLAN 01'),$); +#1906= IFCPROPERTYSINGLEVALUE('Category',$,IFCLABEL('Levels'),$); +#1907= IFCPROPERTYSINGLEVALUE('Family',$,IFCLABEL('Level: 8mm Niv\X2\00E5\X0\hode Lokale Koter'),$); +#1908= IFCPROPERTYSINGLEVALUE('Family and Type',$,IFCLABEL('Level: 8mm Niv\X2\00E5\X0\hode Lokale Koter'),$); +#1909= IFCPROPERTYSINGLEVALUE('Type',$,IFCLABEL('Level: 8mm Niv\X2\00E5\X0\hode Lokale Koter'),$); +#1910= IFCPROPERTYSINGLEVALUE('Type Id',$,IFCLABEL('Level: 8mm Niv\X2\00E5\X0\hode Lokale Koter'),$); +#1911= IFCPROPERTYSINGLEVALUE('Elevation Base',$,IFCIDENTIFIER('Project Base Point'),$); +#1912= IFCPROPERTYSINGLEVALUE('Color',$,IFCINTEGER(0),$); +#1913= IFCPROPERTYSINGLEVALUE('Line Pattern',$,IFCLABEL('Centre'),$); +#1914= IFCPROPERTYSINGLEVALUE('Line Weight',$,IFCIDENTIFIER('1'),$); +#1915= IFCPROPERTYSINGLEVALUE('Symbol',$,IFCLABEL('View - Niv\X2\00E5\X0\hode: Niv\X2\00E5\X0\hode Trekant'),$); +#1916= IFCPROPERTYSINGLEVALUE('Symbol at End 1 Default',$,IFCBOOLEAN(.F.),$); +#1917= IFCPROPERTYSINGLEVALUE('Symbol at End 2 Default',$,IFCBOOLEAN(.T.),$); +#1918= IFCPROPERTYSINGLEVALUE('Type Name',$,IFCTEXT('8mm Niv\X2\00E5\X0\hode Lokale Koter'),$); +#1919= IFCPROPERTYSINGLEVALUE('Family Name',$,IFCTEXT('Level'),$); +#1920= IFCPROPERTYSET('3Zu5Bv0LOHrPC11XI6FoQQ',#42,'Constraints',$,(#1902)); +#1923= IFCRELDEFINESBYPROPERTIES('3Zu5Bv0LOHrPC11nI6FoQQ',#42,$,$,(#140),#1920); +#1927= IFCPROPERTYSET('3Zu5Bv0LOHrPC11WA6FoQQ',#42,'Dimensions',$,(#1903)); +#1930= IFCRELDEFINESBYPROPERTIES('3Zu5Bv0LOHrPC11mA6FoQQ',#42,$,$,(#140),#1927); +#1933= IFCPROPERTYSET('3Zu5Bv0LOHrPC11W66FoQQ',#42,'Identity Data',$,(#1169,#1904,#1905)); +#1937= IFCRELDEFINESBYPROPERTIES('3Zu5Bv0LOHrPC11m66FoQQ',#42,$,$,(#140),#1933); +#1940= IFCPROPERTYSET('2FA06uA3PFMQNbcHaAvqjj',#42,'Other',$,(#1906,#1907,#1908,#1909,#1910)); +#1947= IFCRELDEFINESBYPROPERTIES('0litd1LpDBRBpkKGx9T$S5',#42,$,$,(#140),#1940); +#1950= IFCPROPERTYSET('3Zu5Bv0LOHrPC11XI6FoQS',#42,'Constraints',$,(#1911)); +#1953= IFCPROPERTYSET('3Zu5Bv0LOHrPC11WM6FoQS',#42,'Graphics',$,(#1912,#1913,#1914,#1915,#1916,#1917)); +#1961= IFCPROPERTYSET('3Zu5Bv0LOHrPC11W66FoQS',#42,'Identity Data',$,(#1918)); +#1964= IFCPROPERTYSET('2w96tQqqbFpepd87QA_4lP',#42,'Other',$,(#1906,#1919)); +#1967= IFCRELCONTAINEDINSPATIALSTRUCTURE('3Zu5Bv0LOHrPC10066FoQQ',#42,$,$,(#701,#898,#1066,#1450,#1606,#1664,#1720,#1776),#140); +#1978= IFCPROPERTYSINGLEVALUE('Elevation',$,IFCLENGTHMEASURE(3060.),$); +#1979= IFCPROPERTYSINGLEVALUE('Computation Height',$,IFCLENGTHMEASURE(1650.),$); +#1980= IFCPROPERTYSINGLEVALUE('Name',$,IFCTEXT('PLAN 02'),$); +#1981= IFCPROPERTYSET('34TXSA2TTDdQqr5CiMy0Ob',#42,'Constraints',$,(#1978)); +#1984= IFCRELDEFINESBYPROPERTIES('34TXSA2TTDdQqr5SiMy0Ob',#42,$,$,(#146),#1981); +#1988= IFCPROPERTYSET('34TXSA2TTDdQqr5DqMy0Ob',#42,'Dimensions',$,(#1979)); +#1991= IFCRELDEFINESBYPROPERTIES('34TXSA2TTDdQqr5TqMy0Ob',#42,$,$,(#146),#1988); +#1994= IFCPROPERTYSET('34TXSA2TTDdQqr5DuMy0Ob',#42,'Identity Data',$,(#1169,#1904,#1980)); +#1997= IFCRELDEFINESBYPROPERTIES('34TXSA2TTDdQqr5TuMy0Ob',#42,$,$,(#146),#1994); +#2000= IFCPROPERTYSET('0HRd3FfE9Es8SpPf9AbDpj',#42,'Other',$,(#1906,#1907,#1908,#1909,#1910)); +#2002= IFCRELDEFINESBYPROPERTIES('2DQfuJyFXELQJICDJEI8vW',#42,$,$,(#146),#2000); +#2005= IFCRELCONTAINEDINSPATIALSTRUCTURE('34TXSA2TTDdQqr4juMy0Ob',#42,$,$,(#1030,#1827,#1845),#146); +#2011= IFCRELAGGREGATES('10zuuVffX3Jv03CpcKTsyG',#42,$,$,#106,(#1854)); +#2015= IFCRELAGGREGATES('0ySE4kjJb7IQEcMkONDvhL',#42,$,$,#1854,(#121)); +#2019= IFCRELAGGREGATES('27PCKGLxT4mxtV9cw6mgBW',#42,$,$,#121,(#140,#146)); +#2024= IFCPROPERTYSINGLEVALUE('Building Name',$,IFCTEXT('091'),$); +#2025= IFCPROPERTYSINGLEVALUE('Organization Description',$,IFCTEXT('A - Arkitekt'),$); +#2026= IFCPROPERTYSINGLEVALUE('Organization Name',$,IFCTEXT('PG Campus \X2\00C5\X0\s'),$); +#2027= IFCPROPERTYSINGLEVALUE('Client Name',$,IFCTEXT('Statsbygg'),$); +#2028= IFCPROPERTYSINGLEVALUE('CQDoorSwingCodes',$,IFCTEXT('Left=L;Right=R;notMirrored =;mirrored ='),$); +#2029= IFCPROPERTYSINGLEVALUE('CQPhaseFilter',$,IFCTEXT('Existing:True;New Construction:True;Temporary:True;'),$); +#2030= IFCPROPERTYSINGLEVALUE('Project Address',$,IFCTEXT('Forprosjekt'),$); +#2031= IFCPROPERTYSINGLEVALUE('Project Issue Date',$,IFCTEXT('SB_14323_03_ARK_091'),$); +#2032= IFCPROPERTYSINGLEVALUE('Project Name',$,IFCTEXT('14323'),$); +#2033= IFCPROPERTYSINGLEVALUE('Project Number',$,IFCTEXT('12370'),$); +#2034= IFCPROPERTYSINGLEVALUE('Project Status',$,IFCTEXT('02'),$); +#2035= IFCPROPERTYSET('2SEynX0yz5uQxuaiE4IiyJ',#42,'Identity Data',$,(#1858,#1860,#1861,#2024,#2025,#2026)); +#2040= IFCRELDEFINESBYPROPERTIES('1aRw6GMwvElBEY0jF64TpU',#42,$,$,(#121),#2035); +#2044= IFCPROPERTYSET('2911NfldvE9w6uXVbaFvXD',#42,'Other',$,(#1864,#1867,#2027,#2028,#2029,#2030,#2031,#2032,#2033,#2034)); +#2054= IFCRELDEFINESBYPROPERTIES('2uMCXemlDDof69kUP2ewno',#42,$,$,(#121),#2044); +#2057= IFCRELASSOCIATESMATERIAL('1wrST1aZvCJetfNbIF067B',#42,$,$,(#1066),#1153); +#2061= IFCRELASSOCIATESMATERIAL('2GOrZdWCjDTPYdngHZu_Sn',#42,$,$,(#1155),#1146); +#2065= IFCRELASSOCIATESMATERIAL('2SQ6mTkrjEsx16FeMiz3oX',#42,$,$,(#1606),#1609); +#2069= IFCRELASSOCIATESMATERIAL('2oK1CfU$H1tQdkVHDrIIYf',#42,$,$,(#1664),#1667); +#2073= IFCRELASSOCIATESMATERIAL('2DAF128$v7CAD7HKwHzb4N',#42,$,$,(#1720),#1723); +#2077= IFCRELASSOCIATESMATERIAL('2Tui85BkfAN9NOj1xBEBWu',#42,$,$,(#1776),#1779); +#2081= IFCRELASSOCIATESMATERIAL('2CNeT3b699CRaXImGOUQoV',#42,$,$,(#646),#679); +#2084= IFCRELASSOCIATESMATERIAL('2HHKaNXSTBiuf1wgw$jDSu',#42,$,$,(#701),#716); +#2087= IFCRELASSOCIATESMATERIAL('1jvfaMfm18RxXm6y1sOrTd',#42,$,$,(#898),#901); +#2091= IFCRELASSOCIATESMATERIAL('3vcB1OwLr5ZB2z0AU8V9M0',#42,$,$,(#1406),#1432); +#2094= IFCRELASSOCIATESMATERIAL('3j5TIeGNfF5xW7rwoTszyP',#42,$,$,(#1450),#1453); +#2097= IFCRELDEFINESBYTYPE('3z97E8y9f5I88dNUvhjEgQ',#42,$,$,(#701),#646); +#2101= IFCRELDEFINESBYTYPE('2idYhS38PBD9GOiHzQutED',#42,$,$,(#1066,#1606,#1664,#1720,#1776),#1155); +#2109= IFCRELDEFINESBYTYPE('1rC0Auz_LFgALvGtykUsTn',#42,$,$,(#1450),#1406); +#2113= IFCRELDEFINESBYPROPERTIES('3ezTUOAkD9sOw0yQQg_dAI',#42,$,$,(#898),#987); +#2116= IFCRELDEFINESBYPROPERTIES('29pF_ma0r37xMADUOcx0Uo',#42,$,$,(#898),#990); +#2119= IFCRELDEFINESBYPROPERTIES('2$HZSmMMDEZP0sGNJXPisb',#42,$,$,(#898),#995); +#2122= IFCRELDEFINESBYPROPERTIES('1SLhVKZYvEVQjgjIQKZBGs',#42,$,$,(#898),#999); +#2125= IFCRELDEFINESBYPROPERTIES('1ZLxsh0fjCDRuolTCYCzr3',#42,$,$,(#898),#1003); +#2128= IFCRELDEFINESBYPROPERTIES('005VeXd29DP9UOaXww58OI',#42,$,$,(#140,#146),#1950); +#2131= IFCRELDEFINESBYPROPERTIES('0BzkEEIyX6mg$7DJ6thFc1',#42,$,$,(#140,#146),#1953); +#2134= IFCRELDEFINESBYPROPERTIES('3Yv4JfIObEPfoyGpwJq_Z6',#42,$,$,(#140,#146),#1961); +#2137= IFCRELDEFINESBYPROPERTIES('1fCFSvmcX05O1C30h1grtJ',#42,$,$,(#140,#146),#1964); +#2140= IFCCARTESIANPOINT((460.000000000008,874.999999999999)); +#2142= IFCAXIS2PLACEMENT2D(#2140,#24); +#2143= IFCRECTANGLEPROFILEDEF(.AREA.,$,#2142,920.000000000016,1750.); +#2144= IFCAXIS2PLACEMENT3D(#6,#16,#20); +#2145= IFCEXTRUDEDAREASOLID(#2143,#2144,#20,213.); +#2146= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#2145)); +#2148= IFCPRODUCTDEFINITIONSHAPE($,$,(#2146)); +#2151= IFCCARTESIANPOINT((51348.432734218,-106.500000000174,1200.)); +#2153= IFCAXIS2PLACEMENT3D(#2151,$,$); +#2154= IFCLOCALPLACEMENT(#1037,#2153); +#2156= IFCOPENINGELEMENT('1PTz52_o9DlAOe36su2tDU',#42,'Eks V1:Vindu 3 felt med 3 \X2\00E5\X0\pninger:5304233:1',$,'Opening',#2154,#2148,$,.OPENING.); +#2161= IFCRELVOIDSELEMENT('1PTz52_o9DlAOe36gu2tDU',#42,$,$,#1066,#2156); +#2164= IFCRELFILLSELEMENT('2RI5C5EYf0WgKQFKrHJrgN',#42,$,$,#2156,#1450); +#2167= IFCCARTESIANPOINT((-84.7965385908683,40.,0.)); +#2169= IFCAXIS2PLACEMENT3D(#2167,$,$); +#2173= IFCAXIS2PLACEMENT3D(#6,$,$); +#2291= IFCAXIS2PLACEMENT3D(#2289,$,$); +#2175= IFCAXIS2PLACEMENT3D(#2188,$,$); +#2289= IFCCARTESIANPOINT((41181.,28855.,1050.)); +#2178= IFCCARTESIANPOINT((-5.68434188608080E-14,-4.32009983342141E-12)); +#2180= IFCAXIS2PLACEMENT2D(#2178,#24); +#2181= IFCRECTANGLEPROFILEDEF(.AREA.,'Vindu 1 felt eksisterende',#2180,955.000000000028,1050.); +#2182= IFCCARTESIANPOINT((525.,0.,477.500000000014)); +#2184= IFCAXIS2PLACEMENT3D(#2182,#16,#20); +#2185= IFCEXTRUDEDAREASOLID(#2181,#2184,#20,3048.); +#2186= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#2185)); +#2188= IFCCARTESIANPOINT((41181.,28855.,1050.)); +#2190= IFCPRODUCTDEFINITIONSHAPE($,$,(#2186)); +#2193= IFCCARTESIANPOINT((31266.500000162,-1630.5000000002,1050.)); +#2195= IFCAXIS2PLACEMENT3D(#2193,$,$); +#2196= IFCLOCALPLACEMENT(#1037,#2195); +#2197= IFCOPENINGELEMENT('0HNfUe8E1CBeeczp8rXNWv',#42,'Basic Wall:V10:4932686',$,'Opening',#2196,#2190,$,.OPENING.); +#2200= IFCRELVOIDSELEMENT('3eBR5DHnfAIBOAfK6IPTcw',#42,$,$,#1066,#2197); +#2202= IFCAXIS2PLACEMENT3D(#6,$,$); +#2294= IFCAXIS2PLACEMENT3D(#2292,$,$); +#2204= IFCAXIS2PLACEMENT3D(#2217,$,$); +#2292= IFCCARTESIANPOINT((10925.,28855.,1050.)); +#2207= IFCCARTESIANPOINT((0.,-5.68434188608080E-14)); +#2209= IFCAXIS2PLACEMENT2D(#2207,#28); +#2210= IFCRECTANGLEPROFILEDEF(.AREA.,'Sidehengslet \X2\00E5\X0\pningsvindu 3 felt',#2209,920.000000000016,1750.); +#2211= IFCCARTESIANPOINT((875.,0.,460.)); +#2213= IFCAXIS2PLACEMENT3D(#2211,#16,#14); +#2214= IFCEXTRUDEDAREASOLID(#2210,#2213,#20,3048.); +#2215= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#2214)); +#2217= IFCCARTESIANPOINT((10925.,28855.,1050.)); +#2219= IFCPRODUCTDEFINITIONSHAPE($,$,(#2215)); +#2222= IFCCARTESIANPOINT((1010.50000016201,-1630.5000000002,1050.)); +#2224= IFCAXIS2PLACEMENT3D(#2222,$,$); +#2225= IFCLOCALPLACEMENT(#1037,#2224); +#2226= IFCOPENINGELEMENT('3n3el7tsPBORtUY8_VoM7z',#42,'Basic Wall:V10:4932686',$,'Opening',#2225,#2219,$,.OPENING.); +#2229= IFCRELVOIDSELEMENT('2AF0YiP7L7lfAkYu2KIXhf',#42,$,$,#1066,#2226); +#2231= IFCAXIS2PLACEMENT3D(#6,$,$); +#2297= IFCAXIS2PLACEMENT3D(#2295,$,$); +#2233= IFCAXIS2PLACEMENT3D(#2246,$,$); +#2295= IFCCARTESIANPOINT((14525.,28855.,1050.)); +#2236= IFCCARTESIANPOINT((0.,-5.68434188608080E-14)); +#2238= IFCAXIS2PLACEMENT2D(#2236,#28); +#2239= IFCRECTANGLEPROFILEDEF(.AREA.,'Sidehengslet \X2\00E5\X0\pningsvindu 3 felt',#2238,920.000000000016,1750.); +#2240= IFCCARTESIANPOINT((875.,0.,460.)); +#2242= IFCAXIS2PLACEMENT3D(#2240,#16,#14); +#2243= IFCEXTRUDEDAREASOLID(#2239,#2242,#20,3048.); +#2244= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#2243)); +#2246= IFCCARTESIANPOINT((14525.,28855.,1050.)); +#2248= IFCPRODUCTDEFINITIONSHAPE($,$,(#2244)); +#2251= IFCCARTESIANPOINT((4610.50000016201,-1630.5000000002,1050.)); +#2253= IFCAXIS2PLACEMENT3D(#2251,$,$); +#2254= IFCLOCALPLACEMENT(#1037,#2253); +#2255= IFCOPENINGELEMENT('3n3el7tsPBORtUY8_VoM3Y',#42,'Basic Wall:V10:4932686',$,'Opening',#2254,#2248,$,.OPENING.); +#2258= IFCRELVOIDSELEMENT('0cUXaV6M5BuRg1_EPMcQP$',#42,$,$,#1066,#2255); +#2260= IFCAXIS2PLACEMENT3D(#6,$,$); +#2300= IFCAXIS2PLACEMENT3D(#2298,$,$); +#2262= IFCAXIS2PLACEMENT3D(#2275,$,$); +#2298= IFCCARTESIANPOINT((18125.,28855.,1050.)); +#2265= IFCCARTESIANPOINT((-1.08002495835535E-12,-5.68434188608080E-14)); +#2267= IFCAXIS2PLACEMENT2D(#2265,#28); +#2268= IFCRECTANGLEPROFILEDEF(.AREA.,'Sidehengslet \X2\00E5\X0\pningsvindu 3 felt',#2267,920.000000000016,1750.); +#2269= IFCCARTESIANPOINT((875.,0.,460.)); +#2271= IFCAXIS2PLACEMENT3D(#2269,#16,#14); +#2272= IFCEXTRUDEDAREASOLID(#2268,#2271,#20,3048.); +#2273= IFCSHAPEREPRESENTATION(#100,'Body','SweptSolid',(#2272)); +#2275= IFCCARTESIANPOINT((18125.,28855.,1050.)); +#2277= IFCPRODUCTDEFINITIONSHAPE($,$,(#2273)); +#2280= IFCCARTESIANPOINT((8210.50000016201,-1630.5000000002,1050.)); +#2282= IFCAXIS2PLACEMENT3D(#2280,$,$); +#2283= IFCLOCALPLACEMENT(#1037,#2282); +#2301= IFCPRESENTATIONLAYERASSIGNMENT('A-DETL-____-OTLN',$,(#1024),$); +#2304= IFCPRESENTATIONLAYERASSIGNMENT('A-GENM-____-OTLN',$,(#451,#636,#687,#691),$); +#2310= IFCPRESENTATIONLAYERASSIGNMENT('A-GLAZ-____-OTLN',$,(#1370,#1398,#1436,#1440,#2186,#2215,#2244,#2273),$); +#2320= IFCPRESENTATIONLAYERASSIGNMENT('A-WALL-____-OTLN',$,(#1042,#1060,#1587,#1600,#1645,#1658,#1701,#1714,#1757,#1770,#2146),$); +#2333= IFCPRESENTATIONLAYERASSIGNMENT('G-____-____-TEXT',$,(#1822,#1840),$); +#2337= IFCPRESENTATIONLAYERASSIGNMENT('S-FNDN-____-OTLN',$,(#893),$); +ENDSEC; + +END-ISO-10303-21;