Minor changes to conversion result numbers

This commit is contained in:
Thomas Krijnen
2026-06-23 20:25:57 +02:00
parent dad4cc8a3c
commit c592018b3f
6 changed files with 76 additions and 87 deletions
-8
View File
@@ -1,8 +1,6 @@
#include "ConversionResult.h"
#include "IfcGeomRepresentation.h"
#include <iomanip>
IfcGeom::Representation::Triangulation* IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings, Logger& logger) const
{
auto t = IfcGeom::Representation::Triangulation::empty(settings);
@@ -21,11 +19,5 @@ void IfcGeom::ConversionResult::prepend(ifcopenshell::geometry::taxonomy::matrix
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();
}
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<3>;
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<4>;
+15 -26
View File
@@ -101,6 +101,12 @@ namespace IfcGeom {
virtual const void* value_ptr() const = 0;
};
template <typename T, typename = void>
struct has_exact : std::false_type {};
template <typename T>
struct has_exact<T, std::void_t<decltype(std::declval<const T&>().exact())>> : std::true_type {};
template <typename T>
struct NumberModel : NumberConcept {
T value;
@@ -116,26 +122,19 @@ namespace IfcGeom {
return *same;
}
template <typename U>
static auto stream_exact(std::ostream& os, const U& v, int) -> decltype(os << v.exact(), void()) {
os << v.exact();
}
template <typename U>
static void stream_exact(std::ostream& os, const U& v, long) {
if constexpr (std::is_floating_point<U>::value) {
os << std::setprecision(std::numeric_limits<U>::digits10 + 1);
}
os << v;
}
virtual double to_double() const {
return static_cast<double>(value);
}
virtual std::string to_string() const {
std::stringstream ss;
stream_exact(ss, value, 0);
if constexpr (has_exact<T>::value) {
ss << value.exact();
} else if constexpr (std::is_floating_point<T>::value) {
ss << std::setprecision(std::numeric_limits<T>::digits10 + 1);
}
ss << value;
}
return ss.str();
}
@@ -204,12 +203,14 @@ namespace IfcGeom {
OpaqueNumber() = default;
virtual ~OpaqueNumber() = default;
#ifndef SWIG
template <
typename T,
typename Decayed = std::decay_t<T>,
typename = std::enable_if_t<!std::is_base_of<OpaqueNumber, Decayed>::value && !is_shared_ptr<Decayed>::value>>
explicit OpaqueNumber(T&& value)
: data_(std::make_shared<NumberModel<Decayed>>(std::forward<T>(value))) {}
#endif
double to_double() const {
return data().to_double();
@@ -292,18 +293,6 @@ namespace IfcGeom {
}
};
class IFC_GEOM_API NumberNativeDouble : public OpaqueNumber {
public:
NumberNativeDouble(double v)
: OpaqueNumber(v) {}
double value() const {
return value_as<double>();
}
std::string to_string() const;
};
template <size_t N>
struct IFC_GEOM_API OpaqueCoordinate {
private:
@@ -11,11 +11,10 @@
using IfcGeom::OpaqueNumber;
using IfcGeom::OpaqueCoordinate;
using IfcGeom::NumberNativeDouble;
using IfcGeom::ConversionResultShape;
#ifdef IFOPSH_SIMPLE_KERNEL
#define NumberType NumberNativeDouble
#define NumberType OpaqueNumber
#else
using ifcopenshell::geometry::NumberEpeck;
#define NumberType NumberEpeck
@@ -103,6 +102,15 @@ namespace {
});
}
void apply_normalized_plane_map(const plane_map<Kernel_>& mp, std::list<cgal_plane_t>& planes) {
for (auto& plane : planes) {
auto it = mp.find(normalized_plane_for_map<Kernel_>(plane));
if (it != mp.end()) {
plane = it->second;
}
}
}
cgal_vector_t wire_normal(const cgal_wire_t& wire) {
typename Kernel_::FT a(0), b(0), c(0);
if (wire.size() < 3) {
@@ -1196,6 +1204,7 @@ std::size_t ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::map(OpaqueC
std::size_t mutated = 0;
auto nw = shape_->map(mp, mutated);
shape_ = std::move(nw);
apply_normalized_plane_map(mp, planes_);
return mutated;
}
@@ -1214,6 +1223,7 @@ std::size_t ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::map(const s
std::size_t mutated = 0;
auto nw = shape_->map(mp, mutated);
shape_ = std::move(nw);
apply_normalized_plane_map(mp, planes_);
return mutated;
}
@@ -31,7 +31,6 @@
using IfcGeom::OpaqueNumber;
using IfcGeom::OpaqueCoordinate;
using IfcGeom::NumberNativeDouble;
using IfcGeom::ConversionResultShape;
namespace {
@@ -390,7 +389,7 @@ OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::OpenCascadeShape::length(
GProp_GProps prop;
BRepGProp::LinearProperties(shape_, prop);
double l = prop.Mass();
return NumberNativeDouble(l);
return OpaqueNumber(l);
}
OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::area()
@@ -398,7 +397,7 @@ OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::area()
GProp_GProps prop;
BRepGProp::SurfaceProperties(shape_, prop);
double l = prop.Mass();
return NumberNativeDouble(l);
return OpaqueNumber(l);
}
OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::volume()
@@ -406,7 +405,7 @@ OpaqueNumber ifcopenshell::geometry::OpenCascadeShape::volume()
GProp_GProps prop;
BRepGProp::VolumeProperties(shape_, prop);
double l = prop.Mass();
return NumberNativeDouble(l);
return OpaqueNumber(l);
}
#include <Geom_Plane.hxx>
@@ -419,9 +418,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::position()
if (plane) {
auto loc = plane->Location();
return OpaqueCoordinate<3>(
NumberNativeDouble(loc.X()),
NumberNativeDouble(loc.Y()),
NumberNativeDouble(loc.Z())
OpaqueNumber(loc.X()),
OpaqueNumber(loc.Y()),
OpaqueNumber(loc.Z())
);
}
}
@@ -436,9 +435,9 @@ OpaqueCoordinate<3> ifcopenshell::geometry::OpenCascadeShape::axis()
if (plane) {
auto dir = plane->Axis().Direction();
return OpaqueCoordinate<3>(
NumberNativeDouble(dir.X()),
NumberNativeDouble(dir.Y()),
NumberNativeDouble(dir.Z())
OpaqueNumber(dir.X()),
OpaqueNumber(dir.Y()),
OpaqueNumber(dir.Z())
);
}
}
@@ -454,10 +453,10 @@ OpaqueCoordinate<4> ifcopenshell::geometry::OpenCascadeShape::plane_equation()
double a, b, c, d;
plane->Pln().Coefficients(a, b, c, d);
return OpaqueCoordinate<4>(
NumberNativeDouble(a),
NumberNativeDouble(b),
NumberNativeDouble(c),
NumberNativeDouble(d)
OpaqueNumber(a),
OpaqueNumber(b),
OpaqueNumber(c),
OpaqueNumber(d)
);
}
}
+36 -36
View File
@@ -630,31 +630,31 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
// I couldn't get the vector<string> typemap to be applied when %extending Iterator constructor.
// anyway it does not matter as SWIG generates C code without actual constructors
%inline %{
IfcGeom::Iterator* construct_iterator(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, int num_threads, Logger& logger = Logger::Root()) {
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::entity_filter ef{ include, false, elems_set };
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {ef}, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::attribute_filter af;
af.attribute_name = "GlobalId";
af.populate(elems_set);
af.include = include;
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<int> elems_set(elems.begin(), elems.end());
IfcGeom::instance_id_filter af(include, false, elems_set);
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
}
%}
IfcGeom::Iterator* construct_iterator(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, int num_threads, Logger& logger = Logger::Root()) {
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::entity_filter ef{ include, false, elems_set };
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {ef}, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::attribute_filter af;
af.attribute_name = "GlobalId";
af.populate(elems_set);
af.include = include;
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
std::set<int> elems_set(elems.begin(), elems.end());
IfcGeom::instance_id_filter af(include, false, elems_set);
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
}
%}
%extend IfcGeom::Representation::Triangulation {
@@ -1174,14 +1174,14 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
%template(OpaqueCoordinate_4) IfcGeom::OpaqueCoordinate<4>;
%inline %{
IfcGeom::OpaqueNumber create_epeck(int i) {
return ifcopenshell::geometry::NumberEpeck(i);
IfcGeom::OpaqueNumber create_epeck(int i) {
return ifcopenshell::geometry::NumberEpeck(i);
}
IfcGeom::OpaqueNumber create_epeck(double d) {
return ifcopenshell::geometry::NumberEpeck(d);
IfcGeom::OpaqueNumber create_epeck(double d) {
return ifcopenshell::geometry::NumberEpeck(d);
}
IfcGeom::OpaqueNumber create_epeck(const std::string& s) {
return ifcopenshell::geometry::NumberEpeck(typename CGAL::Epeck::FT::ET(s));
IfcGeom::OpaqueNumber create_epeck(const std::string& s) {
return ifcopenshell::geometry::NumberEpeck(typename CGAL::Epeck::FT::ET(s));
}
%}
@@ -1279,11 +1279,11 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
}
}
std::vector<svgfill::polygon_2> arrange_polygons(svgfill::arrange_polygon_settings settings, const std::vector<svgfill::polygon_2>& polygons, Logger& logger = Logger::Root()) {
std::vector<svgfill::polygon_2> r;
if (svgfill::arrange_polygons(settings, polygons, r, logger)) {
return r;
} else {
std::vector<svgfill::polygon_2> arrange_polygons(svgfill::arrange_polygon_settings settings, const std::vector<svgfill::polygon_2>& polygons, Logger& logger = Logger::Root()) {
std::vector<svgfill::polygon_2> r;
if (svgfill::arrange_polygons(settings, polygons, r, logger)) {
return r;
} else {
throw std::runtime_error("Failed to arrange polygons");
}
}
-1
View File
@@ -59,7 +59,6 @@
%}
%template(DoubleArray3) std::array<double, 3>;
%ignore IfcGeom::NumberNativeDouble;
%ignore ifcopenshell::geometry::Converter;
// Not relevant for python: new_IfcBaseClass() calls instantiate()