mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 18:02:29 +00:00
Taxonomy curve upgrades #4832
This commit is contained in:
+177
-38
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <boost/math/constants/constants.hpp>
|
||||||
|
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
|
||||||
@@ -1116,31 +1117,13 @@ typedef item const* ptr;
|
|||||||
static const size_t max = std::tuple_size<impl::SurfacesTuple>::value;
|
static const size_t max = std::tuple_size<impl::SurfacesTuple>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hacks around not wanting to use if constexpr
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class loop_to_face_upgrade {
|
class loop_to_face_upgrade {
|
||||||
public:
|
|
||||||
loop_to_face_upgrade(taxonomy::ptr) {}
|
|
||||||
|
|
||||||
operator bool() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator taxonomy::face::ptr() const {
|
|
||||||
throw taxonomy::topology_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator typename T::ptr() const {
|
|
||||||
throw taxonomy::topology_error();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class loop_to_face_upgrade<taxonomy::face> {
|
|
||||||
private:
|
private:
|
||||||
boost::optional<taxonomy::face::ptr> face_;
|
boost::optional<taxonomy::face::ptr> face_;
|
||||||
public:
|
public:
|
||||||
loop_to_face_upgrade(taxonomy::ptr item) {
|
loop_to_face_upgrade(taxonomy::ptr item) {
|
||||||
|
if constexpr (std::is_same_v<T, face>) {
|
||||||
auto loop = taxonomy::dcast<taxonomy::loop>(item);
|
auto loop = taxonomy::dcast<taxonomy::loop>(item);
|
||||||
if (loop) {
|
if (loop) {
|
||||||
loop->external = true;
|
loop->external = true;
|
||||||
@@ -1151,42 +1134,154 @@ typedef item const* ptr;
|
|||||||
(*face_)->children = { taxonomy::clone(loop) };
|
(*face_)->children = { taxonomy::clone(loop) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return face_.is_initialized();
|
return face_.is_initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
operator taxonomy::face::ptr() const {
|
operator typename T::ptr() const {
|
||||||
|
if constexpr (std::is_same_v<T, face>) {
|
||||||
|
if (face_) {
|
||||||
return *face_;
|
return *face_;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hacks around not wanting to use if constexpr
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class loop_to_piecewise_function_upgrade {
|
class curve_to_edge_upgrade {
|
||||||
|
private:
|
||||||
|
boost::optional<taxonomy::edge::ptr> edge_;
|
||||||
public:
|
public:
|
||||||
loop_to_piecewise_function_upgrade(taxonomy::ptr) {}
|
curve_to_edge_upgrade(taxonomy::ptr item) {
|
||||||
|
if constexpr (std::is_same_v<T, edge>) {
|
||||||
operator bool() const {
|
auto circle = taxonomy::dcast<taxonomy::circle>(item);
|
||||||
return false;
|
auto ellipse = taxonomy::dcast<taxonomy::ellipse>(item);
|
||||||
|
if (circle || ellipse) {
|
||||||
|
edge_ = taxonomy::make<taxonomy::edge>();
|
||||||
|
if (circle) {
|
||||||
|
(*edge_)->basis = circle;
|
||||||
|
} else {
|
||||||
|
(*edge_)->basis = ellipse;
|
||||||
|
}
|
||||||
|
// @todo make trims optional to allow unbounded edges
|
||||||
|
(*edge_)->start = 0.;
|
||||||
|
(*edge_)->end = 2 * boost::math::constants::pi<double>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator taxonomy::piecewise_function::ptr() const {
|
operator bool() const {
|
||||||
throw taxonomy::topology_error();
|
return edge_.is_initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
operator typename T::ptr() const {
|
operator typename T::ptr() const {
|
||||||
throw taxonomy::topology_error();
|
if constexpr (std::is_same_v<T, edge>) {
|
||||||
|
if (edge_) {
|
||||||
|
return *edge_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class loop_to_piecewise_function_upgrade<taxonomy::piecewise_function> {
|
template <typename T>
|
||||||
|
class curve_to_loop_upgrade {
|
||||||
|
private:
|
||||||
|
boost::optional<taxonomy::loop::ptr> loop_;
|
||||||
|
public:
|
||||||
|
curve_to_loop_upgrade(taxonomy::ptr item) {
|
||||||
|
if constexpr (std::is_same_v<T, loop>) {
|
||||||
|
auto circle = taxonomy::dcast<taxonomy::circle>(item);
|
||||||
|
auto ellipse = taxonomy::dcast<taxonomy::ellipse>(item);
|
||||||
|
if (circle || ellipse) {
|
||||||
|
auto edge = taxonomy::make<taxonomy::edge>();
|
||||||
|
if (circle) {
|
||||||
|
edge->basis = circle;
|
||||||
|
} else {
|
||||||
|
edge->basis = ellipse;
|
||||||
|
}
|
||||||
|
// @todo make trims optional to allow unbounded edges
|
||||||
|
edge->start = 0.;
|
||||||
|
edge->end = 2 * boost::math::constants::pi<double>();
|
||||||
|
|
||||||
|
loop_ = taxonomy::make<taxonomy::loop>();
|
||||||
|
(*loop_)->children.push_back(edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return loop_.is_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator typename T::ptr() const {
|
||||||
|
if constexpr (std::is_same_v<T, loop>) {
|
||||||
|
if (loop_) {
|
||||||
|
return *loop_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class curve_to_face_upgrade {
|
||||||
|
private:
|
||||||
|
boost::optional<taxonomy::face::ptr> face_;
|
||||||
|
public:
|
||||||
|
curve_to_face_upgrade(taxonomy::ptr item) {
|
||||||
|
if constexpr (std::is_same_v<T, edge>) {
|
||||||
|
auto circle = taxonomy::dcast<taxonomy::circle>(item);
|
||||||
|
auto ellipse = taxonomy::dcast<taxonomy::ellipse>(item);
|
||||||
|
if (circle || ellipse) {
|
||||||
|
auto edge = taxonomy::make<taxonomy::edge>();
|
||||||
|
if (circle) {
|
||||||
|
edge->basis = circle;
|
||||||
|
} else {
|
||||||
|
edge->basis = ellipse;
|
||||||
|
}
|
||||||
|
// @todo make trims optional to allow unbounded edges
|
||||||
|
edge->start = 0.;
|
||||||
|
edge->end = 2 * boost::math::constants::pi<double>();
|
||||||
|
|
||||||
|
auto loop = taxonomy::make<taxonomy::loop>();
|
||||||
|
loop->children.push_back(edge);
|
||||||
|
|
||||||
|
face_ = taxonomy::make<taxonomy::face>();
|
||||||
|
(*face_)->instance = loop->instance;
|
||||||
|
(*face_)->matrix = loop->matrix;
|
||||||
|
(*face_)->children = { taxonomy::clone(loop) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return face_.is_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator typename T::ptr() const {
|
||||||
|
if constexpr (std::is_same_v<T, face>) {
|
||||||
|
if (face_) {
|
||||||
|
return *face_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class loop_to_piecewise_function_upgrade {
|
||||||
private:
|
private:
|
||||||
boost::optional<taxonomy::piecewise_function::ptr> pwf_;
|
boost::optional<taxonomy::piecewise_function::ptr> pwf_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
loop_to_piecewise_function_upgrade(taxonomy::ptr item) {
|
loop_to_piecewise_function_upgrade(taxonomy::ptr item) {
|
||||||
|
if constexpr (std::is_same_v<T, piecewise_function>) {
|
||||||
auto loop = taxonomy::dcast<taxonomy::loop>(item);
|
auto loop = taxonomy::dcast<taxonomy::loop>(item);
|
||||||
if (loop) {
|
if (loop) {
|
||||||
if (loop->pwf.is_initialized()) {
|
if (loop->pwf.is_initialized()) {
|
||||||
@@ -1218,26 +1313,54 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return pwf_.is_initialized();
|
return pwf_.is_initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
operator taxonomy::piecewise_function::ptr() const {
|
operator typename T::ptr() const {
|
||||||
|
if constexpr (std::is_same_v<T, piecewise_function>) {
|
||||||
|
if (pwf_) {
|
||||||
return *pwf_;
|
return *pwf_;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TAXONOMY_USE_SHARED_PTR
|
#ifdef TAXONOMY_USE_SHARED_PTR
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::shared_ptr<T> cast(const std::shared_ptr<U>& u) {
|
std::shared_ptr<T> cast(const std::shared_ptr<U>& u) {
|
||||||
|
{
|
||||||
|
curve_to_edge_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
curve_to_loop_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
curve_to_face_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
loop_to_face_upgrade<T> upg(u);
|
loop_to_face_upgrade<T> upg(u);
|
||||||
if (upg) {
|
if (upg) {
|
||||||
return upg;
|
return upg;
|
||||||
}
|
}
|
||||||
loop_to_piecewise_function_upgrade<T> pwupg(u);
|
}
|
||||||
if (pwupg) {
|
{
|
||||||
return pwupg;
|
loop_to_piecewise_function_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (auto r = std::dynamic_pointer_cast<T>(u)) {
|
if (auto r = std::dynamic_pointer_cast<T>(u)) {
|
||||||
return r;
|
return r;
|
||||||
@@ -1247,13 +1370,29 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::shared_ptr<T> dcast(const std::shared_ptr<U>& u) {
|
std::shared_ptr<T> dcast(const std::shared_ptr<U>& u) {
|
||||||
|
{
|
||||||
|
curve_to_edge_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
curve_to_face_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
loop_to_face_upgrade<T> upg(u);
|
loop_to_face_upgrade<T> upg(u);
|
||||||
if (upg) {
|
if (upg) {
|
||||||
return upg;
|
return upg;
|
||||||
}
|
}
|
||||||
loop_to_piecewise_function_upgrade<T> pwupg(u);
|
}
|
||||||
if (pwupg) {
|
{
|
||||||
return pwupg;
|
loop_to_piecewise_function_upgrade<T> upg(u);
|
||||||
|
if (upg) {
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::dynamic_pointer_cast<T>(u);
|
return std::dynamic_pointer_cast<T>(u);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user