Implement mapping of IfcExtrudedAreaSolid

This commit is contained in:
Thomas Krijnen
2019-08-04 11:27:10 +02:00
parent 467ebb68a3
commit dae35f59ce
4 changed files with 97 additions and 16 deletions
+1 -1
View File
@@ -2,6 +2,6 @@
#undef BIND
#endif
#define BIND(T) ifcopenshell::geometry::taxonomy::item* convert(const IfcSchema::T*);
#define BIND(T) ifcopenshell::geometry::taxonomy::item* map(const IfcSchema::T*);
#include "mapping.i"
+55 -1
View File
@@ -22,9 +22,63 @@
#include "../../ifcparse/IfcLogger.h"
using namespace IfcUtil;
using namespace ifcopenshell::geometry;
ifcopenshell::geometry::taxonomy::item* ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)::map(const IfcBaseClass* l) {
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::item* mapping::map(const IfcBaseClass* l) {
#include "bind_convert_impl.i"
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
return nullptr;
}
namespace {
// A RAII-based mechanism to cast the conversion results
// from map() into the right type expected by the higher
// level typology items. An exception is thrown if the
// types do not match or the result was nullptr. A copy
// will be assigned to the higher level topology member
// and the original pointer will be deleted.
// This class is also able to uplift some topology items
// to higher level types, such as a loop to a face, which
// is why the cast operator does not return a reference.
template <typename T>
class as {
private:
taxonomy::item* item_;
public:
as(taxonomy::item* item) : item_(item) {}
operator T() const {
if (!item_) {
throw taxonomy::topology_error;
}
T* t = dynamic_cast<T*>(item_);
if (t) {
return *t;
} else {
if constexpr (std::is_same<T, topology::face>::value) {
topology::loop* loop = dynamic_cast<T*>(item_);
if (loop) {
return topology::face(loop.id, loop.matrix, *loop);
}
}
throw taxonomy::topology_error;
}
}
~as() {
delete item;
}
};
};
taxonomy::item* mapping::map(const IfcSchema::IfcExtrudedAreaSolid* inst) {
return new taxonomy::extrusion(
inst->data().id(),
as<taxonomy::matrix4>(map(inst->Position())),
as<taxonomy::face>(map(inst->SweptArea())),
as<taxonomy::direction3>(map(inst->ExtrudedDirection())),
inst->Depth()
);
}
+1 -2
View File
@@ -20,8 +20,7 @@
/********************************************************************************
* *
* This file registers function prototypes for all supported IFC geometrical *
* entities. For entities of type CLASS an std::map is also created to cache *
* the output of the conversion functions *
* entities. *
* *
********************************************************************************/
+40 -12
View File
@@ -1,5 +1,7 @@
#include <boost/variant.hpp>
#include <exception>
namespace ifcopenshell {
namespace geometry {
@@ -9,6 +11,8 @@ namespace taxonomy {
struct item {
int instance_id;
virtual item* clone() const = 0;
item(int id) : instance_id(id) {}
};
struct matrix4 : public item {
@@ -25,61 +29,78 @@ struct matrix4 : public item {
struct geom_item : public item {
// geometry::style surface_style;
matrix4 matrix;
geom_item(int id) : item(id) {}
geom_item(int id, matrix4 m) : item(id), matrix(m) {}
};
template <size_t N>
struct cartesian_base : public item {
struct cartesian_base : public geom_item {
std::array<double, N> components;
cartesian_base(double x, double y, double z = 0.) : components{ {x, y, z} } {}
};
struct point3 : public cartesian_base<3> {
virtual item* clone() const { return new point3(*this); }
point3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {}
};
struct direction3 : public cartesian_base<3> {
virtual item* clone() const { return new direction3(*this); }
direction3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {}
};
struct line : public item {
struct line : public geom_item {
virtual item* clone() const { return new line(*this); }
};
struct circle : public item {
struct circle : public geom_item {
virtual item* clone() const { return new circle(*this); }
};
struct ellipse : public item {
struct ellipse : public geom_item {
virtual item* clone() const { return new ellipse(*this); }
};
struct bspline : public item {
struct bspline : public geom_item {
virtual item* clone() const { return new bspline(*this); }
};
typedef boost::variant<line, circle, ellipse, bspline> curve;
struct edge : public item {
struct edge : public geom_item {
boost::variant<point3, double> start, end;
boost::optional<curve> basis;
virtual item* clone() const { return new edge(*this); }
};
struct boundary : public item {
struct loop : public geom_item {
std::vector<edge> edges;
virtual item* clone() const { return new boundary(*this); }
virtual item* clone() const { return new loop(*this); }
};
struct face : public item {
boundary outer;
std::vector<boundary> inner;
struct face : public geom_item {
loop outer;
std::vector<loop> inner;
virtual item* clone() const { return new face(*this); }
face(int id, loop o) : geom_item(id), outer(o) {}
face(int id, loop o, std::vector<loop> i) : geom_item(id), outer(o), inner(i) {}
face(int id, matrix4 m, loop o) : geom_item(id, m), outer(o) {}
face(int id, matrix4 m, loop o, std::vector<loop> i) : geom_item(id, m), outer(o), inner(i) {}
};
struct sweep : public item {
struct sweep : public geom_item {
face basis;
sweep(int id, face b) : geom_item(id), basis(b) {}
sweep(int id, matrix4 m, face b) : geom_item(id, m), basis(b) {}
};
struct extrusion : public sweep {
@@ -87,10 +108,17 @@ struct extrusion : public sweep {
double depth;
virtual item* clone() const { return new extrusion(*this); }
extrusion(int id, matrix4 m, face basis, direction3 dir, double d) : sweep(id, m, basis), direction(dir), depth(d) {}
};
class topology_error : public std::runtime_error {
};
}
}
}