mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-19 03:33:48 +00:00
Spatial Querying: Implementation of BVH tree for IFC files using NCollection_UBTree (#130)
* Implementation of BVH tree for IFC files using NCollection_UBTree * Fixes for gcc and OCCT < v6.8 * Enable BVH selection by TopoDS_Shape * Small fixes to tree * Merge conflicted files and other changes * Eliminate one warning (some remain) + add tree test
This commit is contained in:
@@ -36,6 +36,8 @@
|
||||
$result = PyBool_FromLong(static_cast<long>(*$1));
|
||||
}
|
||||
|
||||
%ignore IfcGeom::impl::tree::selector;
|
||||
|
||||
%include "../ifcgeom/ifc_geom_api.h"
|
||||
%include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
%include "../ifcgeom/IfcGeomElement.h"
|
||||
@@ -43,6 +45,63 @@
|
||||
%include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
%include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
// A Template instantantation should be defined before it is used as a base class.
|
||||
// But frankly I don't care as most methods are subtlely different anyway.
|
||||
%include "../ifcgeom/IfcGeomTree.h"
|
||||
|
||||
%extend IfcGeom::tree {
|
||||
|
||||
static IfcEntityList::ptr vector_to_list(const std::vector<IfcSchema::IfcProduct*>& ps) const {
|
||||
IfcEntityList::ptr r(new IfcEntityList);
|
||||
for (std::vector<IfcSchema::IfcProduct*>::const_iterator it = ps.begin(); it != ps.end(); ++it) {
|
||||
r->push(*it);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select_box(IfcUtil::IfcBaseClass* e, bool completely_within = false, double extend=-1.e-5) const {
|
||||
if (!e->is(IfcSchema::Type::IfcProduct)) {
|
||||
throw IfcParse::IfcException("Instance should be an IfcProduct");
|
||||
}
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select_box((IfcSchema::IfcProduct*)e, completely_within, extend);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select_box(const gp_Pnt& p) const {
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select_box(p);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select_box(const Bnd_Box& b, bool completely_within = false) const {
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select_box(b, completely_within);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select(IfcUtil::IfcBaseClass* e, bool completely_within = false) const {
|
||||
if (!e->is(IfcSchema::Type::IfcProduct)) {
|
||||
throw IfcParse::IfcException("Instance should be an IfcProduct");
|
||||
}
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select((IfcSchema::IfcProduct*)e, completely_within);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select(const gp_Pnt& p) const {
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select(p);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
IfcEntityList::ptr select(const std::string& shape_serialization) const {
|
||||
std::stringstream stream(shape_serialization);
|
||||
BRepTools_ShapeSet shapes;
|
||||
shapes.Read(stream);
|
||||
const TopoDS_Shape& shp = shapes.Shape(shapes.NbShapes());
|
||||
|
||||
std::vector<IfcSchema::IfcProduct*> ps = $self->select(shp);
|
||||
return IfcGeom_tree_vector_to_list(ps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
%module ifcopenshell_wrapper %{
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
#include "../ifcgeom/IfcGeomTree.h"
|
||||
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
@@ -108,4 +108,39 @@ CREATE_VECTOR_TYPEMAP_IN(std::string, STRING, str)
|
||||
} else {
|
||||
SWIG_exception(SWIG_TypeError, "Attribute of type AGGREGATE OF AGGREGATE OF ENTITY INSTANCE needs a python sequence of sequence of entity instances");
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(in) const gp_Pnt& {
|
||||
if (!check_aggregate_of_type($input, get_python_type<double>())) {
|
||||
SWIG_exception(SWIG_TypeError, "<Point> type needs a python sequence of 3 floats");
|
||||
}
|
||||
std::vector<double> ds = python_sequence_as_vector<double>($input);
|
||||
if (ds.size() != 3) {
|
||||
SWIG_exception(SWIG_TypeError, "<Point> type needs a python sequence of 3 floats");
|
||||
}
|
||||
$1 = new gp_Pnt(ds[0], ds[1], ds[2]);
|
||||
}
|
||||
|
||||
%typemap(in) const Bnd_Box& {
|
||||
if (!check_aggregate_of_aggregate_of_type($input, get_python_type<double>())) {
|
||||
SWIG_exception(SWIG_TypeError, "<AABB> type needs a python sequence of 2 x 3 floats");
|
||||
}
|
||||
std::vector< std::vector<double> > ds = python_sequence_as_vector_of_vector<double>($input);
|
||||
if (ds.size() != 2) {
|
||||
SWIG_exception(SWIG_TypeError, "<AABB> type needs a python sequence of 2 x 3 floats");
|
||||
}
|
||||
if (ds[0].size() != 3 || ds[1].size() != 3) {
|
||||
SWIG_exception(SWIG_TypeError, "<AABB> type needs a python sequence of 2 x 3 floats");
|
||||
}
|
||||
$1 = new Bnd_Box();
|
||||
$1->Add(gp_Pnt(ds[0][0], ds[0][1], ds[0][2]));
|
||||
$1->Add(gp_Pnt(ds[1][0], ds[1][1], ds[1][2]));
|
||||
}
|
||||
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_INTEGER) const gp_Pnt& {
|
||||
$1 = check_aggregate_of_type($input, get_python_type<double>());
|
||||
}
|
||||
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_INTEGER) const Bnd_Box& {
|
||||
$1 = check_aggregate_of_aggregate_of_type($input, get_python_type<double>());
|
||||
}
|
||||
Reference in New Issue
Block a user