mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Implement mapping of IfcExtrudedAreaSolid
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user