to_string() option, no shared_ptr in OpaqueCoord, add ConvResShape::vertices(), newell instead of simple cross product, create_epeck(double/str)

This commit is contained in:
Thomas Krijnen
2023-12-13 16:43:33 +01:00
parent 14e924cd8c
commit 6ed91d3ea4
8 changed files with 219 additions and 94 deletions
+8
View File
@@ -1,6 +1,8 @@
#include "ConversionResult.h" #include "ConversionResult.h"
#include "IfcGeomRepresentation.h" #include "IfcGeomRepresentation.h"
#include <iomanip>
IfcGeom::Representation::Triangulation * IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings) const IfcGeom::Representation::Triangulation * IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings) const
{ {
auto t = IfcGeom::Representation::Triangulation::empty(settings); auto t = IfcGeom::Representation::Triangulation::empty(settings);
@@ -18,3 +20,9 @@ void IfcGeom::ConversionResult::append(ifcopenshell::geometry::taxonomy::matrix4
void IfcGeom::ConversionResult::prepend(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) { void IfcGeom::ConversionResult::prepend(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) {
placement_ = make<matrix4>(trsf->ccomponents() * placement_->ccomponents()); placement_ = make<matrix4>(trsf->ccomponents() * placement_->ccomponents());
} }
std::string IfcGeom::NumberNativeDouble::to_string() const {
std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::digits10 + 1) << value_;
return ss.str();
}
+18 -9
View File
@@ -71,6 +71,8 @@ namespace IfcGeom {
class IFC_GEOM_API OpaqueNumber { class IFC_GEOM_API OpaqueNumber {
public: public:
virtual double to_double() const = 0; virtual double to_double() const = 0;
virtual std::string to_string() const = 0;
virtual ~OpaqueNumber() {} virtual ~OpaqueNumber() {}
virtual OpaqueNumber* operator+(OpaqueNumber* other) const = 0; virtual OpaqueNumber* operator+(OpaqueNumber* other) const = 0;
@@ -80,6 +82,7 @@ namespace IfcGeom {
virtual bool operator==(OpaqueNumber* other) const = 0; virtual bool operator==(OpaqueNumber* other) const = 0;
virtual bool operator<(OpaqueNumber* other) const = 0; virtual bool operator<(OpaqueNumber* other) const = 0;
virtual OpaqueNumber* operator-() const = 0; virtual OpaqueNumber* operator-() const = 0;
virtual OpaqueNumber* clone() const = 0;
}; };
// @todo this can simply be a template class, to remove the need for the NumberEpeck in CGAL kernel. // @todo this can simply be a template class, to remove the need for the NumberEpeck in CGAL kernel.
@@ -119,10 +122,11 @@ namespace IfcGeom {
return value_; return value_;
} }
virtual std::string to_string() const;
virtual OpaqueNumber* operator+(OpaqueNumber* other) const { virtual OpaqueNumber* operator+(OpaqueNumber* other) const {
return binary_op<add_<double>>(other); return binary_op<add_<double>>(other);
} }
virtual OpaqueNumber* operator-(OpaqueNumber* other) const { virtual OpaqueNumber* operator-(OpaqueNumber* other) const {
return binary_op<subtract_<double>>(other); return binary_op<subtract_<double>>(other);
} }
@@ -141,11 +145,14 @@ namespace IfcGeom {
virtual OpaqueNumber* operator-() const { virtual OpaqueNumber* operator-() const {
return unary_op<negate_<double>>(); return unary_op<negate_<double>>();
} }
virtual OpaqueNumber* clone() const {
return new NumberNativeDouble(value_);
}
}; };
template <size_t N> template <size_t N>
struct IFC_GEOM_API OpaqueCoordinate { struct IFC_GEOM_API OpaqueCoordinate {
std::array<std::shared_ptr<OpaqueNumber>, N> values; std::array<OpaqueNumber*, N> values;
template <typename... Args> template <typename... Args>
OpaqueCoordinate(Args... args) { OpaqueCoordinate(Args... args) {
@@ -159,21 +166,21 @@ namespace IfcGeom {
} }
} }
std::shared_ptr<OpaqueNumber> get(size_t i) { OpaqueNumber* get(size_t i) {
if (i >= N) { if (i >= N) {
return nullptr; return nullptr;
} }
return values[i]; return values[i];
} }
void set(size_t i, std::shared_ptr<OpaqueNumber> n) { void set(size_t i, OpaqueNumber* n) {
if (i < N) { if (i < N) {
values[i] = n; values[i] = n->clone();
} }
} }
private: private:
template <size_t Index, typename... Args> template <size_t Index, typename... Args>
void init_(std::shared_ptr<OpaqueNumber> value, Args... args) { void init_(OpaqueNumber* value, Args... args) {
values[Index] = value; values[Index] = value;
if constexpr (Index + 1 < N) { if constexpr (Index + 1 < N) {
init_<Index + 1>(args...); init_<Index + 1>(args...);
@@ -200,9 +207,9 @@ namespace IfcGeom {
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const = 0; virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const = 0;
virtual void set_box(void* b) = 0; virtual void set_box(void* b) = 0;
virtual std::shared_ptr<OpaqueNumber> length() = 0; virtual OpaqueNumber* length() = 0;
virtual std::shared_ptr<OpaqueNumber> area() = 0; virtual OpaqueNumber* area() = 0;
virtual std::shared_ptr<OpaqueNumber> volume() = 0; virtual OpaqueNumber* volume() = 0;
virtual OpaqueCoordinate<3> position() = 0; virtual OpaqueCoordinate<3> position() = 0;
virtual OpaqueCoordinate<3> axis() = 0; virtual OpaqueCoordinate<3> axis() = 0;
@@ -212,6 +219,8 @@ namespace IfcGeom {
virtual ConversionResultShape* halfspaces() = 0; virtual ConversionResultShape* halfspaces() = 0;
virtual ConversionResultShape* box() = 0; virtual ConversionResultShape* box() = 0;
virtual ConversionResultShape* solid() = 0; virtual ConversionResultShape* solid() = 0;
virtual std::vector<ConversionResultShape*> vertices() = 0;
virtual std::vector<ConversionResultShape*> edges() = 0; virtual std::vector<ConversionResultShape*> edges() = 0;
virtual std::vector<ConversionResultShape*> facets() = 0; virtual std::vector<ConversionResultShape*> facets() = 0;
+117 -55
View File
@@ -21,8 +21,12 @@ using ifcopenshell::geometry::NumberEpeck;
ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t & shape) { ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t & shape) {
shape_ = shape; shape_ = shape;
CGAL::Polygon_mesh_processing::triangulate_faces(*shape_); if (shape.size_of_facets() != 1) {
CGAL::Polygon_mesh_processing::remove_degenerate_faces(*shape_); // this is for handling the specical case of storing a single point in a polyhedron,
// @todo come up with a proper variant for storing lower dimensional entities
CGAL::Polygon_mesh_processing::triangulate_faces(*shape_);
CGAL::Polygon_mesh_processing::remove_degenerate_faces(*shape_);
}
} }
#ifndef IFOPSH_SIMPLE_KERNEL #ifndef IFOPSH_SIMPLE_KERNEL
@@ -63,7 +67,7 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett
m(2, 0), m(2, 1), m(2, 2), m(2, 3)); m(2, 0), m(2, 1), m(2, 2), m(2, 3));
// Apply transformation // Apply transformation
for (auto &vertex : vertices(s)) { for (auto &vertex : s.vertex_handles()) {
vertex->point() = vertex->point().transform(trsf); vertex->point() = vertex->point().transform(trsf);
} }
} }
@@ -185,7 +189,7 @@ void ifcopenshell::geometry::CgalShape::Serialize(const ifcopenshell::geometry::
m(2, 0), m(2, 1), m(2, 2), m(2, 3)); m(2, 0), m(2, 1), m(2, 2), m(2, 3));
// Apply transformation // Apply transformation
for (auto &vertex : vertices(s)) { for (auto &vertex : s.vertex_handles()) {
vertex->point() = vertex->point().transform(trsf); vertex->point() = vertex->point().transform(trsf);
} }
} }
@@ -255,7 +259,7 @@ int ifcopenshell::geometry::CgalShape::num_faces() const
} }
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShape::CgalShape::length() OpaqueNumber* ifcopenshell::geometry::CgalShape::CgalShape::length()
{ {
to_poly(); to_poly();
Kernel_::FT len = 0; Kernel_::FT len = 0;
@@ -265,19 +269,19 @@ std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShape::CgalShape::leng
it->next()->vertex()->point() it->next()->vertex()->point()
).squared_length()); ).squared_length());
} }
return std::make_shared<NumberType>(len); return new NumberType(len);
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShape::area() OpaqueNumber* ifcopenshell::geometry::CgalShape::area()
{ {
to_poly(); to_poly();
return std::make_shared<NumberType>(CGAL::Polygon_mesh_processing::area(*shape_)); return new NumberType(CGAL::Polygon_mesh_processing::area(*shape_));
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShape::volume() OpaqueNumber* ifcopenshell::geometry::CgalShape::volume()
{ {
to_poly(); to_poly();
return std::make_shared<NumberType>(CGAL::Polygon_mesh_processing::volume(*shape_)); return new NumberType(CGAL::Polygon_mesh_processing::volume(*shape_));
} }
OpaqueCoordinate<3> ifcopenshell::geometry::CgalShape::position() OpaqueCoordinate<3> ifcopenshell::geometry::CgalShape::position()
@@ -297,9 +301,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::CgalShape::position()
p[i] /= N; p[i] /= N;
} }
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberType>(p[0]), new NumberType(p[0]),
std::make_shared<NumberType>(p[1]), new NumberType(p[1]),
std::make_shared<NumberType>(p[2]) new NumberType(p[2])
); );
} else { } else {
throw std::runtime_error("Invalid shape type"); throw std::runtime_error("Invalid shape type");
@@ -307,15 +311,25 @@ OpaqueCoordinate<3> ifcopenshell::geometry::CgalShape::position()
} }
namespace { namespace {
template <typename Facet>
CGAL::Direction_3<Kernel_> newell(Facet& face) {
typename Kernel_::FT a(0), b(0), c(0);
CGAL::Polyhedron_3<Kernel_>::Halfedge_around_facet_const_circulator current_halfedge = face.facet_begin();
do {
auto& curr = current_halfedge->vertex()->point();
auto& next = current_halfedge->next()->vertex()->point();
a += (curr.y() - next.y()) * (curr.z() + next.z());
b += (curr.z() - next.z()) * (curr.x() + next.x());
c += (curr.x() - next.x()) * (curr.y() + next.y());
} while (++current_halfedge != face.facet_begin());
return CGAL::Direction_3<Kernel_>(a, b, c);
}
struct Plane_equation { struct Plane_equation {
template <class Facet> template <typename Facet>
typename Facet::Plane_3 operator()(Facet& f) { typename Facet::Plane_3 operator()(Facet& face) {
// @todo from the docs, but better use Newell's method typename Facet::Halfedge_handle h = face.halfedge();
typename Facet::Halfedge_handle h = f.halfedge(); return typename Facet::Plane_3(h->vertex()->point(), newell(face));
typedef typename Facet::Plane_3 Plane;
return Plane(h->vertex()->point(),
h->next()->vertex()->point(),
h->next()->next()->vertex()->point());
} }
}; };
} }
@@ -331,9 +345,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::CgalShape::axis()
auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel; auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel;
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberType>(pl.a() / maxval), new NumberType(pl.a() / maxval),
std::make_shared<NumberType>(pl.b() / maxval), new NumberType(pl.b() / maxval),
std::make_shared<NumberType>(pl.c() / maxval) new NumberType(pl.c() / maxval)
); );
} else { } else {
throw std::runtime_error("Invalid shape type"); throw std::runtime_error("Invalid shape type");
@@ -390,9 +404,52 @@ ConversionResultShape * ifcopenshell::geometry::CgalShape::box()
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::vertices()
{
// @todo this is ridiculous
to_poly();
std::vector<ConversionResultShape*> result;
for (auto& p : shape_->points()) {
std::vector<cgal_point_t> ps = {
p, p, p
};
std::vector<std::vector<size_t>> ids(1);
ids.front().push_back(0);
ids.front().push_back(1);
ids.front().push_back(2);
cgal_shape_t poly;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(ps, ids, poly);
result.push_back(new CgalShape(poly));
}
return result;
}
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::edges() std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::edges()
{ {
throw std::runtime_error("Not implemented"); // @todo this is ridiculous
to_poly();
std::vector<ConversionResultShape*> result;
for (auto& ed : shape_->edges()) {
std::vector<cgal_point_t> ps = {
ed.vertex()->point(),
ed.vertex()->point(),
ed.next()->vertex()->point()
};
std::vector<std::vector<size_t>> ids(1);
ids.front().push_back(0);
ids.front().push_back(1);
ids.front().push_back(2);
cgal_shape_t poly;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(ps, ids, poly);
result.push_back(new CgalShape(poly));
}
return result;
} }
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::facets() std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShape::facets()
@@ -463,7 +520,7 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::moved(ifcopenshell::ge
m(2, 0), m(2, 1), m(2, 2), m(2, 3)); m(2, 0), m(2, 1), m(2, 2), m(2, 3));
// Apply transformation // Apply transformation
for (auto &vertex : vertices(s)) { for (auto &vertex : s.vertex_handles()) {
vertex->point() = vertex->point().transform(trsf); vertex->point() = vertex->point().transform(trsf);
} }
} }
@@ -515,17 +572,17 @@ int ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::num_faces() const
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::CgalShapeHalfSpaceDecomposition::length() OpaqueNumber* ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::CgalShapeHalfSpaceDecomposition::length()
{ {
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::area() OpaqueNumber* ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::area()
{ {
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::volume() OpaqueNumber* ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::volume()
{ {
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
@@ -535,9 +592,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::pos
if (planes_.size() == 1) { if (planes_.size() == 1) {
auto xyz = CGAL::ORIGIN + planes_.front().d() * CGAL::Vector_3<Kernel_>(planes_.front().a(), planes_.front().b(), planes_.front().c()); auto xyz = CGAL::ORIGIN + planes_.front().d() * CGAL::Vector_3<Kernel_>(planes_.front().a(), planes_.front().b(), planes_.front().c());
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberType>(xyz.cartesian(0)), new NumberType(xyz.cartesian(0)),
std::make_shared<NumberType>(xyz.cartesian(1)), new NumberType(xyz.cartesian(1)),
std::make_shared<NumberType>(xyz.cartesian(2)) new NumberType(xyz.cartesian(2))
); );
} else { } else {
throw std::runtime_error("Invalid shape type"); throw std::runtime_error("Invalid shape type");
@@ -552,9 +609,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::axi
auto maxel = std::max_element(abc.begin(), abc.end()); auto maxel = std::max_element(abc.begin(), abc.end());
auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel; auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel;
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberType>(planes_.front().a() / maxval), new NumberType(planes_.front().a() / maxval),
std::make_shared<NumberType>(planes_.front().b() / maxval), new NumberType(planes_.front().b() / maxval),
std::make_shared<NumberType>(planes_.front().c() / maxval) new NumberType(planes_.front().c() / maxval)
); );
} else { } else {
throw std::runtime_error("Invalid shape type"); throw std::runtime_error("Invalid shape type");
@@ -569,10 +626,10 @@ OpaqueCoordinate<4> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::pla
auto maxel = std::max_element(abc.begin(), abc.end()); auto maxel = std::max_element(abc.begin(), abc.end());
auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel; auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel;
return OpaqueCoordinate<4>( return OpaqueCoordinate<4>(
std::make_shared<NumberType>(planes_.front().a() / maxval), new NumberType(planes_.front().a() / maxval),
std::make_shared<NumberType>(planes_.front().b() / maxval), new NumberType(planes_.front().b() / maxval),
std::make_shared<NumberType>(planes_.front().c() / maxval), new NumberType(planes_.front().c() / maxval),
std::make_shared<NumberType>(planes_.front().d() / maxval) new NumberType(planes_.front().d() / maxval)
); );
} else { } else {
throw std::runtime_error("Invalid shape type"); throw std::runtime_error("Invalid shape type");
@@ -599,6 +656,11 @@ ConversionResultShape * ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition:
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::vertices()
{
throw std::runtime_error("Not implemented");
}
std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::edges() std::vector<ConversionResultShape*> ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::edges()
{ {
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
@@ -646,16 +708,16 @@ void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::map(OpaqueCoordina
plane_map<Kernel_> mp; plane_map<Kernel_> mp;
mp.insert({ mp.insert({
CGAL::Plane_3<Kernel_>( CGAL::Plane_3<Kernel_>(
std::static_pointer_cast<NumberEpeck>(from.values[0])->value(), static_cast<NumberEpeck*>(from.values[0])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[1])->value(), static_cast<NumberEpeck*>(from.values[1])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[2])->value(), static_cast<NumberEpeck*>(from.values[2])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[3])->value() static_cast<NumberEpeck*>(from.values[3])->value()
), ),
CGAL::Plane_3<Kernel_>( CGAL::Plane_3<Kernel_>(
std::static_pointer_cast<NumberEpeck>(to.values[0])->value(), static_cast<NumberEpeck*>(to.values[0])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[1])->value(), static_cast<NumberEpeck*>(to.values[1])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[2])->value(), static_cast<NumberEpeck*>(to.values[2])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[3])->value() static_cast<NumberEpeck*>(to.values[3])->value()
) )
}); });
auto nw = shape_->map(mp); auto nw = shape_->map(mp);
@@ -674,16 +736,16 @@ void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::map(const std::vec
auto& to = *jt; auto& to = *jt;
mp.insert({ mp.insert({
CGAL::Plane_3<Kernel_>( CGAL::Plane_3<Kernel_>(
std::static_pointer_cast<NumberEpeck>(from.values[0])->value(), static_cast<NumberEpeck*>(from.values[0])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[1])->value(), static_cast<NumberEpeck*>(from.values[1])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[2])->value(), static_cast<NumberEpeck*>(from.values[2])->value(),
std::static_pointer_cast<NumberEpeck>(from.values[3])->value() static_cast<NumberEpeck*>(from.values[3])->value()
), ),
CGAL::Plane_3<Kernel_>( CGAL::Plane_3<Kernel_>(
std::static_pointer_cast<NumberEpeck>(to.values[0])->value(), static_cast<NumberEpeck*>(to.values[0])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[1])->value(), static_cast<NumberEpeck*>(to.values[1])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[2])->value(), static_cast<NumberEpeck*>(to.values[2])->value(),
std::static_pointer_cast<NumberEpeck>(to.values[3])->value() static_cast<NumberEpeck*>(to.values[3])->value()
) )
}); });
} }
@@ -132,10 +132,18 @@ namespace ifcopenshell { namespace geometry {
NumberEpeck(const CGAL::Epeck::FT& v) NumberEpeck(const CGAL::Epeck::FT& v)
: value_(v) {} : value_(v) {}
virtual ~NumberEpeck() { }
virtual double to_double() const { virtual double to_double() const {
return CGAL::to_double(value_); return CGAL::to_double(value_);
} }
virtual std::string to_string() const {
std::stringstream ss;
ss << value_.exact();
return ss.str();
}
const CGAL::Epeck::FT& value() const { const CGAL::Epeck::FT& value() const {
return value_; return value_;
} }
@@ -161,6 +169,9 @@ namespace ifcopenshell { namespace geometry {
virtual OpaqueNumber* operator-() const { virtual OpaqueNumber* operator-() const {
return unary_op<negate_<CGAL::Epeck::FT>>(); return unary_op<negate_<CGAL::Epeck::FT>>();
} }
virtual OpaqueNumber* clone() const {
return new NumberEpeck(value_);
}
}; };
#endif #endif
@@ -217,9 +228,9 @@ namespace ifcopenshell { namespace geometry {
// @todo this must be something with a virtual dtor so that we can delete it. // @todo this must be something with a virtual dtor so that we can delete it.
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const; virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
virtual std::shared_ptr<OpaqueNumber> length(); virtual OpaqueNumber* length();
virtual std::shared_ptr<OpaqueNumber> area(); virtual OpaqueNumber* area();
virtual std::shared_ptr<OpaqueNumber> volume(); virtual OpaqueNumber* volume();
virtual OpaqueCoordinate<3> position(); virtual OpaqueCoordinate<3> position();
virtual OpaqueCoordinate<3> axis(); virtual OpaqueCoordinate<3> axis();
@@ -229,6 +240,8 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* halfspaces(); virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid(); virtual ConversionResultShape* solid();
virtual ConversionResultShape* box(); virtual ConversionResultShape* box();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges(); virtual std::vector<ConversionResultShape*> edges();
virtual std::vector<ConversionResultShape*> facets(); virtual std::vector<ConversionResultShape*> facets();
@@ -274,9 +287,9 @@ namespace ifcopenshell { namespace geometry {
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const; virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
virtual void set_box(void* b); virtual void set_box(void* b);
virtual std::shared_ptr<OpaqueNumber> length(); virtual OpaqueNumber* length();
virtual std::shared_ptr<OpaqueNumber> area(); virtual OpaqueNumber* area();
virtual std::shared_ptr<OpaqueNumber> volume(); virtual OpaqueNumber* volume();
virtual OpaqueCoordinate<3> position(); virtual OpaqueCoordinate<3> position();
virtual OpaqueCoordinate<3> axis(); virtual OpaqueCoordinate<3> axis();
@@ -286,6 +299,8 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* halfspaces(); virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid(); virtual ConversionResultShape* solid();
virtual ConversionResultShape* box(); virtual ConversionResultShape* box();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges(); virtual std::vector<ConversionResultShape*> edges();
virtual std::vector<ConversionResultShape*> facets(); virtual std::vector<ConversionResultShape*> facets();
@@ -257,28 +257,28 @@ int ifcopenshell::geometry::OpenCascadeShape::num_faces() const
return IfcGeom::util::count(shape_, TopAbs_FACE); return IfcGeom::util::count(shape_, TopAbs_FACE);
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape::length() OpaqueNumber* ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape::length()
{ {
GProp_GProps prop; GProp_GProps prop;
BRepGProp::LinearProperties(shape_, prop); BRepGProp::LinearProperties(shape_, prop);
double l = prop.Mass(); double l = prop.Mass();
return std::make_shared<NumberNativeDouble>(l); return new NumberNativeDouble(l);
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::OpenCascadeShape::area() OpaqueNumber* ifcopenshell::geometry::OpenCascadeShape::area()
{ {
GProp_GProps prop; GProp_GProps prop;
BRepGProp::SurfaceProperties(shape_, prop); BRepGProp::SurfaceProperties(shape_, prop);
double l = prop.Mass(); double l = prop.Mass();
return std::make_shared<NumberNativeDouble>(l); return new NumberNativeDouble(l);
} }
std::shared_ptr<OpaqueNumber> ifcopenshell::geometry::OpenCascadeShape::volume() OpaqueNumber* ifcopenshell::geometry::OpenCascadeShape::volume()
{ {
GProp_GProps prop; GProp_GProps prop;
BRepGProp::VolumeProperties(shape_, prop); BRepGProp::VolumeProperties(shape_, prop);
double l = prop.Mass(); double l = prop.Mass();
return std::make_shared<NumberNativeDouble>(l); return new NumberNativeDouble(l);
} }
#include <Geom_Plane.hxx> #include <Geom_Plane.hxx>
@@ -291,9 +291,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::position()
if (plane) { if (plane) {
auto loc = plane->Location(); auto loc = plane->Location();
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberNativeDouble>(loc.X()), new NumberNativeDouble(loc.X()),
std::make_shared<NumberNativeDouble>(loc.Y()), new NumberNativeDouble(loc.Y()),
std::make_shared<NumberNativeDouble>(loc.Z()) new NumberNativeDouble(loc.Z())
); );
} }
} }
@@ -308,9 +308,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::axis()
if (plane) { if (plane) {
auto dir = plane->Axis().Direction(); auto dir = plane->Axis().Direction();
return OpaqueCoordinate<3>( return OpaqueCoordinate<3>(
std::make_shared<NumberNativeDouble>(dir.X()), new NumberNativeDouble(dir.X()),
std::make_shared<NumberNativeDouble>(dir.Y()), new NumberNativeDouble(dir.Y()),
std::make_shared<NumberNativeDouble>(dir.Z()) new NumberNativeDouble(dir.Z())
); );
} }
} }
@@ -326,10 +326,10 @@ OpaqueCoordinate<4> ifcopenshell::geometry::OpenCascadeShape::plane_equation()
double a, b, c, d; double a, b, c, d;
plane->Pln().Coefficients(a, b, c, d); plane->Pln().Coefficients(a, b, c, d);
return OpaqueCoordinate<4>( return OpaqueCoordinate<4>(
std::make_shared<NumberNativeDouble>(a), new NumberNativeDouble(a),
std::make_shared<NumberNativeDouble>(b), new NumberNativeDouble(b),
std::make_shared<NumberNativeDouble>(c), new NumberNativeDouble(c),
std::make_shared<NumberNativeDouble>(d) new NumberNativeDouble(d)
); );
} }
} }
@@ -356,6 +356,17 @@ ConversionResultShape * ifcopenshell::geometry::OpenCascadeShape::box()
throw std::runtime_error("Not implemented"); throw std::runtime_error("Not implemented");
} }
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::vertices()
{
TopTools_IndexedMapOfShape map;
TopExp::MapShapes(shape_, TopAbs_VERTEX, map);
std::vector<ConversionResultShape*> vec;
for (int i = 1; i <= map.Extent(); ++i) {
vec.push_back(new OpenCascadeShape(map.FindKey(i)));
}
return vec;
}
std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::edges() std::vector<ConversionResultShape*> ifcopenshell::geometry::OpenCascadeShape::edges()
{ {
TopTools_IndexedMapOfShape map; TopTools_IndexedMapOfShape map;
@@ -75,9 +75,9 @@ namespace ifcopenshell {
// @todo this must be something with a virtual dtor so that we can delete it. // @todo this must be something with a virtual dtor so that we can delete it.
virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const; virtual std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> bounding_box() const;
virtual std::shared_ptr<OpaqueNumber> length(); virtual OpaqueNumber* length();
virtual std::shared_ptr<OpaqueNumber> area(); virtual OpaqueNumber* area();
virtual std::shared_ptr<OpaqueNumber> volume(); virtual OpaqueNumber* volume();
virtual OpaqueCoordinate<3> position(); virtual OpaqueCoordinate<3> position();
virtual OpaqueCoordinate<3> axis(); virtual OpaqueCoordinate<3> axis();
@@ -87,6 +87,8 @@ namespace ifcopenshell {
virtual ConversionResultShape* halfspaces(); virtual ConversionResultShape* halfspaces();
virtual ConversionResultShape* solid(); virtual ConversionResultShape* solid();
virtual ConversionResultShape* box(); virtual ConversionResultShape* box();
virtual std::vector<ConversionResultShape*> vertices();
virtual std::vector<ConversionResultShape*> edges(); virtual std::vector<ConversionResultShape*> edges();
virtual std::vector<ConversionResultShape*> facets(); virtual std::vector<ConversionResultShape*> facets();
+23 -3
View File
@@ -58,6 +58,8 @@
} }
} }
%newobject IfcGeom::Representation::BRep::item;
%newobject IfcGeom::ConversionResultShape::halfspaces; %newobject IfcGeom::ConversionResultShape::halfspaces;
%newobject IfcGeom::ConversionResultShape::box; %newobject IfcGeom::ConversionResultShape::box;
%newobject IfcGeom::ConversionResultShape::solid; %newobject IfcGeom::ConversionResultShape::solid;
@@ -65,8 +67,18 @@
%newobject IfcGeom::ConversionResultShape::subtract; %newobject IfcGeom::ConversionResultShape::subtract;
%newobject IfcGeom::ConversionResultShape::intersect; %newobject IfcGeom::ConversionResultShape::intersect;
%newobject IfcGeom::ConversionResultShape::moved; %newobject IfcGeom::ConversionResultShape::moved;
%newobject IfcGeom::ConversionResultShape::area;
%newobject IfcGeom::ConversionResultShape::volume;
%newobject IfcGeom::ConversionResultShape::length;
%newobject nary_union; %newobject nary_union;
%newobject IfcGeom::OpaqueNumber::operator+;
%newobject IfcGeom::OpaqueNumber::operator-;
%newobject IfcGeom::OpaqueNumber::operator*;
%newobject IfcGeom::OpaqueNumber::operator/;
%include "../ifcgeom/ifc_geom_api.h" %include "../ifcgeom/ifc_geom_api.h"
%include "../ifcgeom/Converter.h" %include "../ifcgeom/Converter.h"
%include "../ifcgeom/ConversionResult.h" %include "../ifcgeom/ConversionResult.h"
@@ -640,15 +652,23 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%template(OpaqueCoordinate_3) IfcGeom::OpaqueCoordinate<3>; %template(OpaqueCoordinate_3) IfcGeom::OpaqueCoordinate<3>;
%template(OpaqueCoordinate_4) IfcGeom::OpaqueCoordinate<4>; %template(OpaqueCoordinate_4) IfcGeom::OpaqueCoordinate<4>;
%newobject create_epeck;
%inline %{ %inline %{
std::shared_ptr<IfcGeom::OpaqueNumber> create_epeck(int i) { IfcGeom::OpaqueNumber* create_epeck(int i) {
return std::make_shared<ifcopenshell::geometry::NumberEpeck>(i); return new ifcopenshell::geometry::NumberEpeck(i);
}
IfcGeom::OpaqueNumber* create_epeck(double d) {
return new ifcopenshell::geometry::NumberEpeck(d);
}
IfcGeom::OpaqueNumber* create_epeck(const std::string& s) {
return new ifcopenshell::geometry::NumberEpeck(typename CGAL::Epeck::FT::ET(s));
} }
%} %}
%inline %{ %inline %{
IfcGeom::ConversionResultShape* nary_union(PyObject* sequence) { IfcGeom::ConversionResultShape* nary_union(PyObject* sequence) {
CGAL::Nef_nary_union_3< CGAL::Nef_polyhedron_3<Kernel_> > accum; CGAL::Nef_nary_union_3< CGAL::Nef_polyhedron_3<CGAL::Epeck> > accum;
for(Py_ssize_t i = 0; i < PySequence_Size(sequence); ++i) { for(Py_ssize_t i = 0; i < PySequence_Size(sequence); ++i) {
PyObject* element = PySequence_GetItem(sequence, i); PyObject* element = PySequence_GetItem(sequence, i);
void* argp1 = nullptr; void* argp1 = nullptr;
-2
View File
@@ -52,9 +52,7 @@
%include "std_vector.i" %include "std_vector.i"
%include "std_string.i" %include "std_string.i"
%include "exception.i" %include "exception.i"
%include "std_shared_ptr.i"
%shared_ptr(IfcGeom::OpaqueNumber);
%ignore IfcGeom::NumberNativeDouble; %ignore IfcGeom::NumberNativeDouble;
%ignore ifcopenshell::geometry::Converter; %ignore ifcopenshell::geometry::Converter;