Fixes double unit conversion when convert-back-units are used

(cherry picked from commit 52d894298e)
This commit is contained in:
Richard Brice
2026-07-10 07:55:51 -07:00
committed by Dion Moult
parent 018695a2a9
commit 3cb614485a
+51 -49
View File
@@ -48,28 +48,28 @@
%typemap(out) double& {
$result = SWIG_From_double(*$1);
}
%typemap(out) bool& {
$result = PyBool_FromLong(static_cast<long>(*$1));
}
%typemap(out) IfcGeom::OpaqueNumber {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(new IfcGeom::OpaqueNumber($1)), SWIGTYPE_p_IfcGeom__OpaqueNumber, SWIG_POINTER_OWN);
}
%typemap(in) const IfcGeom::OpaqueNumber& (IfcGeom::OpaqueNumber temp) {
void* argp = nullptr;
int res = SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_IfcGeom__OpaqueNumber, 0);
if (!SWIG_IsOK(res) || !argp) {
SWIG_exception_fail(SWIG_ArgError(res), "Expected IfcGeom::OpaqueNumber");
}
temp = *reinterpret_cast<IfcGeom::OpaqueNumber*>(argp);
$1 = &temp;
}
// Using RTTI return a more specialized type of Element
// Note that these elements are not to be owned by SWIG/Python as they will be freed automatically upon the next iteration
// except for the IfcGeom::Element instances which are returned by Iterator::getObject() calls
%typemap(out) IfcGeom::Element* {
%typemap(out) bool& {
$result = PyBool_FromLong(static_cast<long>(*$1));
}
%typemap(out) IfcGeom::OpaqueNumber {
$result = SWIG_NewPointerObj(SWIG_as_voidptr(new IfcGeom::OpaqueNumber($1)), SWIGTYPE_p_IfcGeom__OpaqueNumber, SWIG_POINTER_OWN);
}
%typemap(in) const IfcGeom::OpaqueNumber& (IfcGeom::OpaqueNumber temp) {
void* argp = nullptr;
int res = SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_IfcGeom__OpaqueNumber, 0);
if (!SWIG_IsOK(res) || !argp) {
SWIG_exception_fail(SWIG_ArgError(res), "Expected IfcGeom::OpaqueNumber");
}
temp = *reinterpret_cast<IfcGeom::OpaqueNumber*>(argp);
$1 = &temp;
}
// Using RTTI return a more specialized type of Element
// Note that these elements are not to be owned by SWIG/Python as they will be freed automatically upon the next iteration
// except for the IfcGeom::Element instances which are returned by Iterator::getObject() calls
%typemap(out) IfcGeom::Element* {
IfcGeom::SerializedElement* serialized_elem = dynamic_cast<IfcGeom::SerializedElement*>($1);
IfcGeom::TriangulationElement* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement*>($1);
IfcGeom::BRepElement* brep_elem = dynamic_cast<IfcGeom::BRepElement*>($1);
@@ -976,7 +976,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
static std::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> helper_fn_create_shape(logger& logger, const std::string& geometry_library, ifcopenshell::geometry::Settings& st, const express::Base& instance, const express::Base& representation = express::Base()) {
ifcopenshell::file* file = instance.file();
ifcopenshell::geometry::Converter kernel(ifcopenshell::geometry::kernels::construct(file, geometry_library, st), file, st, logger);
ifcopenshell::geometry::Converter kernel(ifcopenshell::geometry::kernels::construct(file, geometry_library, st), file, st, logger);
if (instance.declaration().is("IfcProduct")) {
if (representation && !representation.declaration().is("IfcRepresentation")) {
throw ifcopenshell::exception("Supplied representation not of type IfcRepresentation");
@@ -1010,12 +1010,14 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
if (item == nullptr) {
throw ifcopenshell::exception("Failed to convert placement");
}
/*
if (st.get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
// we pass the settings to the Transformation object, but access the data just offloads to the
// generic cartesian_base<Matrix4> so there's no time to apply the settings to the translation part.
item = ifcopenshell::geometry::taxonomy::matrix4::ptr(item->clone_());
item->components().col(3).head<3>() /= kernel.settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
}
*/
return new IfcGeom::Transformation(kernel.settings(), item);
} else {
if (!representation) {
@@ -1087,14 +1089,14 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
%}
%inline %{
static std::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> create_shape(ifcopenshell::geometry::Settings& settings, const express::Base& instance, const express::Base& representation, const char* const geometry_library="opencascade", logger* logger = nullptr) {
return helper_fn_create_shape(logger_or_root(logger), geometry_library, settings, instance, representation);
}
// Manual definition of overload without representation argument
static std::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> create_shape(ifcopenshell::geometry::Settings& settings, const express::Base& instance, const char* const geometry_library="opencascade", logger* logger = nullptr) {
return create_shape(settings, instance, express::Base(), geometry_library, logger);
}
static std::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> create_shape(ifcopenshell::geometry::Settings& settings, const express::Base& instance, const express::Base& representation, const char* const geometry_library="opencascade", logger* logger = nullptr) {
return helper_fn_create_shape(logger_or_root(logger), geometry_library, settings, instance, representation);
}
// Manual definition of overload without representation argument
static std::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> create_shape(ifcopenshell::geometry::Settings& settings, const express::Base& instance, const char* const geometry_library="opencascade", logger* logger = nullptr) {
return create_shape(settings, instance, express::Base(), geometry_library, logger);
}
%}
// @todo bring back serialization OCCT -> IFC by means of opencascade_geometry_ifc_writer_registry
@@ -1105,16 +1107,16 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
%newobject create_epeck;
%inline %{
IfcGeom::OpaqueNumber* create_epeck(int i) {
return new IfcGeom::OpaqueNumber(i);
}
IfcGeom::OpaqueNumber* create_epeck(double d) {
return new IfcGeom::OpaqueNumber(d);
}
IfcGeom::OpaqueNumber* create_epeck(const std::string& s) {
return new IfcGeom::OpaqueNumber(std::stod(s));
}
%}
IfcGeom::OpaqueNumber* create_epeck(int i) {
return new IfcGeom::OpaqueNumber(i);
}
IfcGeom::OpaqueNumber* create_epeck(double d) {
return new IfcGeom::OpaqueNumber(d);
}
IfcGeom::OpaqueNumber* create_epeck(const std::string& s) {
return new IfcGeom::OpaqueNumber(std::stod(s));
}
%}
%inline %{
IfcGeom::ConversionResultShape* nary_union(PyObject* sequence) {
@@ -1244,11 +1246,11 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
%template(OpaqueCoordinate_3) IfcGeom::OpaqueCoordinate<3>;
%template(OpaqueCoordinate_4) IfcGeom::OpaqueCoordinate<4>;
#if 0
%inline %{
IfcGeom::OpaqueNumber create_epeck(int i) {
return ifcopenshell::geometry::NumberEpeck(i);
}
#if 0
%inline %{
IfcGeom::OpaqueNumber create_epeck(int i) {
return ifcopenshell::geometry::NumberEpeck(i);
}
IfcGeom::OpaqueNumber create_epeck(double d) {
return ifcopenshell::geometry::NumberEpeck(d);
}
@@ -1281,9 +1283,9 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
shp = new ifcopenshell::geometry::CgalShape(accum.get_union());
Py_END_ALLOW_THREADS;
return shp;
}
%}
#endif
}
%}
#endif
%extend IfcGeom::ConversionResultShape {
std::string serialize_obj() {