From 830a03ffcd4875c34eb7c8864710b992d9ec100d Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 20 Dec 2017 11:10:27 +0100 Subject: [PATCH] Schema agnostic iterator --- src/ifcconvert/ColladaSerializer.h | 2 +- src/ifcconvert/GeometrySerializer.h | 3 +- src/ifcconvert/IfcConvert.cpp | 2 +- src/ifcconvert/OpenCascadeBasedSerializer.h | 2 +- src/ifcconvert/StepSerializer.h | 2 +- src/ifcgeom/IfcGeomIteratorImplementation.cpp | 4 +- src/ifcgeom/IfcGeomIteratorImplementation.h | 8 +- src/iterator/IfcGeomIterator.h | 115 ++++++++++++++++++ src/iterator/IteratorImplementation.cpp | 11 ++ src/iterator/IteratorImplementation.h | 37 ++++-- 10 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 src/iterator/IfcGeomIterator.h diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h index 3acf29ee8b..e3940c5f24 100644 --- a/src/ifcconvert/ColladaSerializer.h +++ b/src/ifcconvert/ColladaSerializer.h @@ -41,7 +41,7 @@ #pragma GCC diagnostic pop #endif -#include "../ifcgeom/IfcGeomIterator.h" +#include "../iterator/IfcGeomIterator.h" #include "../ifcconvert/GeometrySerializer.h" diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h index 8543c468cb..688c58243a 100644 --- a/src/ifcconvert/GeometrySerializer.h +++ b/src/ifcconvert/GeometrySerializer.h @@ -27,7 +27,8 @@ typedef float real_t; #endif #include "../ifcconvert/Serializer.h" -#include "../ifcgeom/IfcGeomIterator.h" +#include "../iterator/IfcGeomIterator.h" +#include "../ifcgeom/IfcGeomElement.h" class SerializerSettings : public IfcGeom::IteratorSettings { diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 31708c6a9c..efb919a970 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -33,7 +33,7 @@ #include "../ifcconvert/XmlSerializer.h" #include "../ifcconvert/SvgSerializer.h" -#include "../ifcgeom/IfcGeomIterator.h" +#include "../iterator/IfcGeomIterator.h" #include #include diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.h b/src/ifcconvert/OpenCascadeBasedSerializer.h index 01c088594d..523b99e2e4 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.h +++ b/src/ifcconvert/OpenCascadeBasedSerializer.h @@ -20,7 +20,7 @@ #ifndef OPENCASCADEBASEDSERIALIZER_H #define OPENCASCADEBASEDSERIALIZER_H -#include "../ifcgeom/IfcGeomIterator.h" +#include "../iterator/IfcGeomIterator.h" #include "../ifcconvert/GeometrySerializer.h" diff --git a/src/ifcconvert/StepSerializer.h b/src/ifcconvert/StepSerializer.h index e4a6567495..622c8fcb67 100644 --- a/src/ifcconvert/StepSerializer.h +++ b/src/ifcconvert/StepSerializer.h @@ -23,7 +23,7 @@ #include #include -#include "../ifcgeom/IfcGeomIterator.h" +#include "../iterator/IfcGeomIterator.h" #include "../ifcconvert/OpenCascadeBasedSerializer.h" diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.cpp b/src/ifcgeom/IfcGeomIteratorImplementation.cpp index 6c6dffecdd..77e9b6718e 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.cpp +++ b/src/ifcgeom/IfcGeomIteratorImplementation.cpp @@ -17,13 +17,13 @@ void MAKE_INIT_FN(IteratorImplementation_)() { static const std::string schema_name = TOSTRING(IfcSchema); struct { - IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { + IfcGeom::IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)(settings, file); } } factory_float; struct { - IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { + IfcGeom::IteratorImplementation* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)(settings, file); } } factory_double; diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.h b/src/ifcgeom/IfcGeomIteratorImplementation.h index 998d49bf40..2c4c5f68e8 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -337,7 +337,7 @@ namespace IfcGeom { std::string getLog() const { return Logger::GetLog(); } - IfcParse::IfcFile* getFile() const { return ifc_file; } + IfcParse::IfcFile* file() const { return ifc_file; } const std::vector& filters() const { return filters_; } std::vector& filters() { return filters_; } @@ -536,7 +536,7 @@ namespace IfcGeom { // get the parent try { - parent_object = getObject(ret->parent_id()); + parent_object = get_object(ret->parent_id()); } catch (const std::exception& e) { Logger::Error(e); hasParent = false; @@ -550,7 +550,7 @@ namespace IfcGeom { { // Find the next parent try { - parent_object = getObject(parent_object->parent_id()); + parent_object = get_object(parent_object->parent_id()); } catch (const std::exception& e) { Logger::Error(e); hasParent = false; @@ -577,7 +577,7 @@ namespace IfcGeom { return current_shape_model; } - const Element

* getObject(int id) { + const Element

* get_object(int id) { gp_Trsf trsf; int parent_id = -1; std::string instance_type, product_name, product_guid; diff --git a/src/iterator/IfcGeomIterator.h b/src/iterator/IfcGeomIterator.h new file mode 100644 index 0000000000..2a954abe70 --- /dev/null +++ b/src/iterator/IfcGeomIterator.h @@ -0,0 +1,115 @@ +/******************************************************************************** + * * + * This file is part of IfcOpenShell. * + * * + * IfcOpenShell is free software: you can redistribute it and/or modify * + * it under the terms of the Lesser GNU General Public License as published by * + * the Free Software Foundation, either version 3.0 of the License, or * + * (at your option) any later version. * + * * + * IfcOpenShell is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Lesser GNU General Public License for more details. * + * * + * You should have received a copy of the Lesser GNU General Public License * + * along with this program. If not, see . * + * * + ********************************************************************************/ + +/******************************************************************************** + * * + * Geometrical data in an IFC file consists of shapes (IfcShapeRepresentation) * + * and instances (SUBTYPE OF IfcBuildingElement e.g. IfcWindow). * + * * + * IfcGeom::Representation::Triangulation is a class that represents a * + * triangulated IfcShapeRepresentation. * + * Triangulation.verts is a 1 dimensional vector of float defining the * + * cartesian coordinates of the vertices of the triangulated shape in the * + * format of [x1,y1,z1,..,xn,yn,zn] * + * Triangulation.faces is a 1 dimensional vector of int containing the * + * indices of the triangles referencing positions in Triangulation.verts * + * Triangulation.edges is a 1 dimensional vector of int in {0,1} that dictates* + * the visibility of the edges that span the faces in Triangulation.faces * + * * + * IfcGeom::Element represents the actual IfcBuildingElements. * + * IfcGeomObject.name is the GUID of the element * + * IfcGeomObject.type is the datatype of the element e.g. IfcWindow * + * IfcGeomObject.mesh is a pointer to an IfcMesh * + * IfcGeomObject.transformation.matrix is a 4x3 matrix that defines the * + * orientation and translation of the mesh in relation to the world origin * + * * + * IfcGeom::Iterator::initialize() * + * finds the most suitable representation contexts. Returns true iff * + * at least a single representation will process successfully * + * * + * IfcGeom::Iterator::get() * + * returns a pointer to the current IfcGeom::Element * + * * + * IfcGeom::Iterator::next() * + * returns true iff a following entity is available for a successive call to * + * IfcGeom::Iterator::get() * + * * + * IfcGeom::Iterator::progress() * + * returns an int in [0..100] that indicates the overall progress * + * * + ********************************************************************************/ + +#ifndef IFCGEOMITERATOR_H +#define IFCGEOMITERATOR_H + +#include "../iterator/IteratorImplementation.h" + +// The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif + +namespace IfcGeom { + + template + class Iterator { + private: + Iterator(const Iterator&); // N/I + Iterator& operator=(const Iterator&); // N/I + + IfcParse::IfcFile* file_; + IfcGeom::IteratorSettings settings_; + IteratorImplementation* implementation_; + + public: + Iterator(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) + : file_(file) + , settings_(settings) + { + implementation_ = iterator_implementations().construct(file_->schema()->name()); + } + + bool initialize() { + return implementation_->initialize(); + } + + int progress() const { return implementation_->progress(); } + + std::string& unit_name() const { return implementation_->getUnitName(); } + + double unit_magnitude() const { return implementation_->getUnitMagnitude(); } + + IfcParse::IfcFile* file() const { return implementation_->getFile(); } + + IfcUtil::IfcBaseClass* next() const { return implementation_->next(); } + + Element

* get() { return implementation_->get(); } + + BRepElement

* get_native() { return implementation_->get_native(); } + + const Element

* get_object(int id) { return implementation_->get_object(id); } + + IfcUtil::IfcBaseClass* create() { return implementation_->create(); } + }; +} + +#endif diff --git a/src/iterator/IteratorImplementation.cpp b/src/iterator/IteratorImplementation.cpp index 99b7cdbc9b..df6109916d 100644 --- a/src/iterator/IteratorImplementation.cpp +++ b/src/iterator/IteratorImplementation.cpp @@ -22,5 +22,16 @@ void IteratorFactoryImplementation

::bind(const std::string& schema_name, type this->insert(std::make_pair(schema_name, fn)); } +template +IfcGeom::IteratorImplementation

* IteratorFactoryImplementation

::construct(const std::string& schema_name, const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) { + std::map::type>::const_iterator it; + it = this->find(schema_name); + if (it == end()) { + throw IfcParse::IfcException("No geometry iterator registered for " + schema_name); + } + return it->second(settings, file); +} + + template IteratorFactoryImplementation; template IteratorFactoryImplementation; diff --git a/src/iterator/IteratorImplementation.h b/src/iterator/IteratorImplementation.h index d1cb24966d..70992f1419 100644 --- a/src/iterator/IteratorImplementation.h +++ b/src/iterator/IteratorImplementation.h @@ -9,11 +9,19 @@ #include #include -template -class IteratorImplementation; +namespace IfcGeom { + template + class IteratorImplementation; -typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_fn; -typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_double_fn; + template + class Element; + + template + class BRepElement; +} + +typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_fn; +typedef boost::function2*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_double_fn; template struct get_factory_type {}; @@ -33,6 +41,7 @@ class IteratorFactoryImplementation : public std::map::type fn); + IfcGeom::IteratorImplementation

* construct(const std::string& schema_name, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*); }; template @@ -46,9 +55,23 @@ public: } }; -template -class IteratorImplementation { +namespace IfcGeom { -}; + template + class IteratorImplementation { + public: + virtual bool initialize() = 0; + virtual int progress() const = 0; + virtual const std::string& getUnitName() const = 0; + virtual double getUnitMagnitude() const = 0; + virtual IfcParse::IfcFile* file() const = 0; + virtual IfcUtil::IfcBaseClass* next() = 0; + virtual Element

* get() = 0; + virtual BRepElement

* get_native() = 0; + virtual const Element

* get_object(int id) = 0; + virtual IfcUtil::IfcBaseClass* create() = 0; + }; + +} #endif \ No newline at end of file