Fix transformation in serialization element, accept geometry library in more geom functions

This commit is contained in:
Thomas Krijnen
2023-08-26 11:35:23 +02:00
parent 5336b2f987
commit 4bb3cc5c90
10 changed files with 67 additions and 35 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ namespace IfcGeom {
public:
virtual void Triangulate(const IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const = 0;
virtual void Serialize(std::string&) const = 0;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0;
virtual ConversionResultShape* clone() const = 0;
virtual int surface_genus() const = 0;
virtual bool is_manifold() const = 0;
+3 -2
View File
@@ -173,12 +173,13 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
if (brep.begin() != brep.end()) {
if (dynamic_cast<ifcopenshell::geometry::OpenCascadeShape*>(brep.begin()->Shape())) {
ConversionResultShape* shape = brep.as_compound();
shape->Serialize(brep_data_);
ifcopenshell::geometry::taxonomy::matrix4 identity;
shape->Serialize(identity, brep_data_);
delete shape;
} else {
for (auto it = brep.begin(); it != brep.end(); ++it) {
std::string part;
it->Shape()->Serialize(part);
it->Shape()->Serialize(*it->Placement(), part);
if (brep_data_.size()) {
brep_data_ = brep_data_ + "\n---\n" + part;
} else {
@@ -102,9 +102,26 @@ void ifcopenshell::geometry::CgalShape::Triangulate(const IfcGeom::IteratorSetti
}
void ifcopenshell::geometry::CgalShape::Serialize(std::string& r) const {
void ifcopenshell::geometry::CgalShape::Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string& r) const {
cgal_shape_t s = shape_;
if (!place.is_identity()) {
const auto& m = place.ccomponents();
// @todo check
const cgal_placement_t trsf(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3));
// Apply transformation
for (auto &vertex : vertices(s)) {
vertex->point() = vertex->point().transform(trsf);
}
}
std::stringstream sstream;
sstream << shape_;
sstream << s;
r = sstream.str();
}
@@ -96,7 +96,7 @@ namespace ifcopenshell { namespace geometry {
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Serialize(std::string&) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
virtual IfcGeom::ConversionResultShape* clone() const {
return new CgalShape(shape_);
@@ -2,6 +2,7 @@
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/IfcGeomRepresentation.h"
#include "base_utils.h"
#include <TopoDS.hxx>
#include <Geom_SphericalSurface.hxx>
@@ -217,9 +218,10 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
BRepTools::Clean(shape_);
}
void ifcopenshell::geometry::OpenCascadeShape::Serialize(std::string& r) const {
void ifcopenshell::geometry::OpenCascadeShape::Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string& r) const {
auto s = IfcGeom::util::apply_transformation(shape_, place);
std::stringstream sstream;
BRepTools::Write(shape_, sstream);
BRepTools::Write(s, sstream);
r = sstream.str();
}
@@ -49,7 +49,7 @@ namespace ifcopenshell {
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Serialize(std::string&) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
virtual IfcGeom::ConversionResultShape* clone() const {
return new OpenCascadeShape(shape_);
@@ -138,10 +138,6 @@ public:
bool convert(const taxonomy::solid::ptr, TopoDS_Shape&);
bool convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const taxonomy::matrix4& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t);
virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
+17 -1
View File
@@ -286,15 +286,31 @@ TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp
}
}
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
if (t.Form() == gp_Other) {
return BRepBuilderAPI_GTransform(s, t, true);
} else {
return apply_transformation(s, t.Trsf());
}
}
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const ifcopenshell::geometry::taxonomy::matrix4& t) {
// @todo this probably discards non-uniform scale?
gp_GTrsf trsf;
if (t.components_) {
gp_Trsf tr;
const auto& m = t.ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
return apply_transformation(s, trsf);
}
bool IfcGeom::util::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol) {
TopExp_Explorer exp(b, TopAbs_FACE);
if (!exp.More()) {
+1 -1
View File
@@ -66,10 +66,10 @@ namespace IfcGeom {
bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen = 0.1);
double shape_volume(const TopoDS_Shape& s);
double face_area(const TopoDS_Face& f);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
+20 -20
View File
@@ -217,25 +217,25 @@ 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_with_include_exclude(IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::entity_filter ef{ include, false, elems_set };
return new IfcGeom::Iterator(settings, file, {ef}, num_threads);
return new IfcGeom::Iterator(geometry_library, settings, file, {ef}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
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(settings, file, {af}, num_threads);
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads) {
std::set<int> elems_set(elems.begin(), elems.end());
IfcGeom::instance_id_filter af(include, false, elems_set);
return new IfcGeom::Iterator(settings, file, {af}, num_threads);
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
}
%}
@@ -373,10 +373,10 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
}
template <typename Schema>
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> helper_fn_create_shape(IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> helper_fn_create_shape(const std::string& geometry_library, IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
IfcParse::IfcFile* file = instance->data().file;
ifcopenshell::geometry::Converter kernel("opencascade", file, settings);
ifcopenshell::geometry::Converter kernel(geometry_library, file, settings);
if (instance->declaration().is(Schema::IfcProduct::Class())) {
if (representation) {
@@ -501,62 +501,62 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%}
%inline %{
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0, const char* const geometry_library="opencascade") {
const std::string& schema_name = instance->declaration().schema()->name();
#ifdef HAS_SCHEMA_2x3
if (schema_name == "IFC2X3") {
return helper_fn_create_shape<Ifc2x3>(settings, instance, representation);
return helper_fn_create_shape<Ifc2x3>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4
if (schema_name == "IFC4") {
return helper_fn_create_shape<Ifc4>(settings, instance, representation);
return helper_fn_create_shape<Ifc4>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x1
if (schema_name == "IFC4X1") {
return helper_fn_create_shape<Ifc4x1>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x1>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x2
if (schema_name == "IFC4X2") {
return helper_fn_create_shape<Ifc4x2>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x2>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc1
if (schema_name == "IFC4X3_RC1") {
return helper_fn_create_shape<Ifc4x3_rc1>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_rc1>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc2
if (schema_name == "IFC4X3_RC2") {
return helper_fn_create_shape<Ifc4x3_rc2>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_rc2>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc3
if (schema_name == "IFC4X3_RC3") {
return helper_fn_create_shape<Ifc4x3_rc3>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_rc3>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc4
if (schema_name == "IFC4X3_RC4") {
return helper_fn_create_shape<Ifc4x3_rc4>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_rc4>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3
if (schema_name == "IFC4X3") {
return helper_fn_create_shape<Ifc4x3>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_tc1
if (schema_name == "IFC4X3_TC1") {
return helper_fn_create_shape<Ifc4x3_tc1>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_tc1>(geometry_library, settings, instance, representation);
}
#endif
#ifdef HAS_SCHEMA_4x3_add1
if (schema_name == "IFC4X3_ADD1") {
return helper_fn_create_shape<Ifc4x3_add1>(settings, instance, representation);
return helper_fn_create_shape<Ifc4x3_add1>(geometry_library, settings, instance, representation);
}
#endif