mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-20 12:12:15 +00:00
Own iterator geometry results
Return independent geometry copies with unique ownership, preserve parent lifetimes, and teach the Python wrapper to own derived results. Keep serializer inputs non-owning and replace Collada's deferred object with copied triangulation elements.\n\nGenerated with the assistance of an AI coding tool.
This commit is contained in:
+27
-11
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "../ifcparse/argument.h"
|
||||
#include "../ifcparse/global_id.h"
|
||||
@@ -73,8 +74,20 @@ namespace ifcopenshell::geom {
|
||||
std::string _context;
|
||||
std::string _unique_id;
|
||||
ifcopenshell::geom::transformation _transformation;
|
||||
const express::entity product_;
|
||||
const express::entity product_;
|
||||
std::vector<const ifcopenshell::geom::element*> _parents;
|
||||
std::vector<std::shared_ptr<const ifcopenshell::geom::element>> _parent_storage;
|
||||
|
||||
friend class iterator;
|
||||
virtual std::unique_ptr<element> clone() const { return std::make_unique<element>(*this); }
|
||||
void set_parents(std::vector<std::unique_ptr<ifcopenshell::geom::element>>&& newparents) {
|
||||
_parents.clear();
|
||||
_parent_storage.clear();
|
||||
for (auto& parent : newparents) {
|
||||
_parents.push_back(parent.get());
|
||||
_parent_storage.emplace_back(std::move(parent));
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
friend bool operator == (const element& element1, const element& element2) {
|
||||
@@ -108,9 +121,12 @@ namespace ifcopenshell::geom {
|
||||
const std::string& context() const { return _context; }
|
||||
const std::string& unique_id() const { return _unique_id; }
|
||||
const ifcopenshell::geom::transformation& transformation() const { return _transformation; }
|
||||
const express::entity& product() const { return product_; }
|
||||
const express::entity& product() const { return product_; }
|
||||
const std::vector<const ifcopenshell::geom::element*>& parents() const { return _parents; }
|
||||
void SetParents(std::vector<const ifcopenshell::geom::element*>& newparents) { _parents = newparents; }
|
||||
void SetParents(std::vector<const ifcopenshell::geom::element*>& newparents) {
|
||||
_parent_storage.clear();
|
||||
_parents = newparents;
|
||||
}
|
||||
|
||||
element(const ifcopenshell::geom::settings& settings, int id, int parent_id, const std::string& name, const std::string& type,
|
||||
const std::string& guid, const std::string& context, const ifcopenshell::geom::taxonomy::matrix4::ptr& trsf, const express::entity& product)
|
||||
@@ -158,9 +174,10 @@ namespace ifcopenshell::geom {
|
||||
bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const {
|
||||
return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z);
|
||||
}
|
||||
brep_element(const brep_element& other) = default;
|
||||
private:
|
||||
brep_element(const brep_element& other);
|
||||
brep_element& operator=(const brep_element& other);
|
||||
std::unique_ptr<element> clone() const override { return std::make_unique<brep_element>(*this); }
|
||||
};
|
||||
|
||||
class triangulation_element : public element {
|
||||
@@ -177,26 +194,25 @@ namespace ifcopenshell::geom {
|
||||
: element(source)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
triangulation_element(const triangulation_element& other) = default;
|
||||
private:
|
||||
triangulation_element(const triangulation_element& other);
|
||||
triangulation_element& operator=(const triangulation_element& other);
|
||||
std::unique_ptr<element> clone() const override { return std::make_unique<triangulation_element>(*this); }
|
||||
};
|
||||
|
||||
class serialized_element : public element {
|
||||
private:
|
||||
ifcopenshell::geom::Representation::serialization* _geometry;
|
||||
boost::shared_ptr<ifcopenshell::geom::Representation::serialization> _geometry;
|
||||
public:
|
||||
const ifcopenshell::geom::Representation::serialization& geometry() const { return *_geometry; }
|
||||
serialized_element(const brep_element& shape_model)
|
||||
: element(shape_model)
|
||||
, _geometry(new ifcopenshell::geom::Representation::serialization(shape_model.geometry()))
|
||||
, _geometry(boost::shared_ptr<ifcopenshell::geom::Representation::serialization>(new ifcopenshell::geom::Representation::serialization(shape_model.geometry())))
|
||||
{}
|
||||
virtual ~serialized_element() {
|
||||
delete _geometry;
|
||||
}
|
||||
serialized_element(const serialized_element& other) = default;
|
||||
private:
|
||||
serialized_element(const serialized_element& other);
|
||||
serialized_element& operator=(const serialized_element& other);
|
||||
std::unique_ptr<element> clone() const override { return std::make_unique<serialized_element>(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+15
-16
@@ -301,8 +301,8 @@ void ifcopenshell::geom::iterator::compute_bounds(bool with_geometry)
|
||||
if (with_geometry) {
|
||||
size_t num_created = 0;
|
||||
do {
|
||||
ifcopenshell::geom::element* geom_object = get();
|
||||
const ifcopenshell::geom::triangulation_element* o = static_cast<const ifcopenshell::geom::triangulation_element*>(geom_object);
|
||||
auto geom_object = get();
|
||||
const ifcopenshell::geom::triangulation_element* o = static_cast<const ifcopenshell::geom::triangulation_element*>(geom_object.get());
|
||||
const ifcopenshell::geom::Representation::triangulation& mesh = o->geometry();
|
||||
auto mat = o->transformation().data()->ccomponents();
|
||||
Eigen::Vector4d vec, transformed;
|
||||
@@ -548,7 +548,7 @@ express::base ifcopenshell::geom::iterator::next() {
|
||||
}
|
||||
|
||||
/// Gets the representation of the current geometrical entity.
|
||||
ifcopenshell::geom::element* ifcopenshell::geom::iterator::get()
|
||||
std::unique_ptr<ifcopenshell::geom::element> ifcopenshell::geom::iterator::get()
|
||||
{
|
||||
validate_iterator_state();
|
||||
|
||||
@@ -558,24 +558,24 @@ ifcopenshell::geom::element* ifcopenshell::geom::iterator::get()
|
||||
if (settings_.get<ifcopenshell::geom::settings::UseElementHierarchy>().get()) {
|
||||
// We are going to build a vector with the element parents.
|
||||
// First, create the parent vector
|
||||
std::vector<const ifcopenshell::geom::element*> parents;
|
||||
std::vector<std::unique_ptr<ifcopenshell::geom::element>> parents;
|
||||
|
||||
// if the element has a parent
|
||||
if (ret->parent_id() != -1) {
|
||||
const ifcopenshell::geom::element* parent_object = NULL;
|
||||
ifcopenshell::geom::element* parent_object = NULL;
|
||||
bool hasParent = true;
|
||||
|
||||
// get the parent
|
||||
try {
|
||||
parent_object = get_object(ret->parent_id());
|
||||
auto parent = get_object(ret->parent_id());
|
||||
parent_object = parent.get();
|
||||
parents.insert(parents.begin(), std::move(parent));
|
||||
} catch (const std::exception& e) {
|
||||
logger_.error("GEO", 56, e);
|
||||
hasParent = false;
|
||||
}
|
||||
|
||||
// Add the previously found parent to the vector
|
||||
if (hasParent) parents.insert(parents.begin(), parent_object);
|
||||
|
||||
// We need to find all the parents
|
||||
while (parent_object != NULL && hasParent && parent_object->parent_id() != -1) {
|
||||
// Find the next parent
|
||||
@@ -585,7 +585,9 @@ ifcopenshell::geom::element* ifcopenshell::geom::iterator::get()
|
||||
hasParent = false;
|
||||
} else {
|
||||
try {
|
||||
parent_object = get_object(pid);
|
||||
auto parent = get_object(pid);
|
||||
parent_object = parent.get();
|
||||
parents.insert(parents.begin(), std::move(parent));
|
||||
} catch (const std::exception& e) {
|
||||
logger_.error("GEO", 57, e);
|
||||
hasParent = false;
|
||||
@@ -593,20 +595,18 @@ ifcopenshell::geom::element* ifcopenshell::geom::iterator::get()
|
||||
}
|
||||
|
||||
// Add the previously found parent to the vector
|
||||
if (hasParent) parents.insert(parents.begin(), parent_object);
|
||||
|
||||
hasParent = hasParent && parent_object->parent_id() != -1;
|
||||
}
|
||||
|
||||
// when done push the parent list in the element object
|
||||
ret->SetParents(parents);
|
||||
ret->set_parents(std::move(parents));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret->clone();
|
||||
}
|
||||
|
||||
const ifcopenshell::geom::element* ifcopenshell::geom::iterator::get_object(int id) {
|
||||
std::unique_ptr<ifcopenshell::geom::element> ifcopenshell::geom::iterator::get_object(int id) {
|
||||
ifcopenshell::geom::taxonomy::matrix4::ptr m4;
|
||||
int parent_id = -1;
|
||||
std::string instance_type, product_name, product_guid;
|
||||
@@ -639,8 +639,7 @@ const ifcopenshell::geom::element* ifcopenshell::geom::iterator::get_object(int
|
||||
logger_.error("GEO", 59, "Unknown error returning product");
|
||||
}
|
||||
|
||||
element* ifc_object = new element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product.as<express::entity>());
|
||||
return ifc_object;
|
||||
return std::make_unique<element>(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product.as<express::entity>());
|
||||
}
|
||||
|
||||
express::base ifcopenshell::geom::iterator::create() {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
* at least a single representation will process successfully *
|
||||
* *
|
||||
* ifcopenshell::geom::iterator::get() *
|
||||
* returns a pointer to the current ifcopenshell::geom::element *
|
||||
* returns an owned copy of the current ifcopenshell::geom::element *
|
||||
* *
|
||||
* ifcopenshell::geom::iterator::next() *
|
||||
* returns true iff a following entity is available for a successive call to *
|
||||
@@ -291,15 +291,16 @@ namespace ifcopenshell::geom {
|
||||
express::base next();
|
||||
|
||||
/// Gets the representation of the current geometrical entity.
|
||||
element* get();
|
||||
std::unique_ptr<element> get();
|
||||
|
||||
/// Gets the native (Open Cascade or CGAL) representation of the current geometrical entity.
|
||||
brep_element* get_native()
|
||||
std::unique_ptr<brep_element> get_native()
|
||||
{
|
||||
return *native_task_result_iterator_;
|
||||
validate_iterator_state();
|
||||
return std::make_unique<brep_element>(**native_task_result_iterator_);
|
||||
}
|
||||
|
||||
const element* get_object(int id);
|
||||
std::unique_ptr<element> get_object(int id);
|
||||
|
||||
express::base create();
|
||||
};
|
||||
|
||||
@@ -1496,7 +1496,8 @@ namespace ifcopenshell::geom {
|
||||
void add_file(ifcopenshell::geom::iterator& it) {
|
||||
if (it.initialize()) {
|
||||
do {
|
||||
add_element(dynamic_cast<ifcopenshell::geom::brep_element*>(it.get()));
|
||||
auto element = it.get();
|
||||
add_element(dynamic_cast<ifcopenshell::geom::brep_element*>(element.get()));
|
||||
} while (it.next());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ namespace ifcopenshell {
|
||||
ifcopenshell::geom::iterator iterator(ifcopenshell::geom::kernels::construct(&file, "opencascade", settings_), settings_, &file, {}, 1);
|
||||
if (iterator.initialize()) {
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
auto element = iterator.get();
|
||||
add_element(element.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
}
|
||||
@@ -139,7 +140,8 @@ namespace ifcopenshell {
|
||||
ifcopenshell::geom::iterator iterator(ifcopenshell::geom::kernels::construct(&file, "opencascade", settings_), settings_, &file, {}, 1);
|
||||
if (iterator.initialize()) {
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
auto element = iterator.get();
|
||||
add_element(element.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,8 @@ void ifcopenshell::geom::tree::add_file(ifcopenshell::geom::iterator& iterator)
|
||||
}
|
||||
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
auto element = iterator.get();
|
||||
add_element(element.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user