mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 02:31:09 +00:00
Fix #244 and provide instances by entity type without subtypes
This commit is contained in:
@@ -73,7 +73,7 @@ namespace Type {
|
|||||||
} Enum;
|
} Enum;
|
||||||
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
||||||
IFC_PARSE_API Enum FromString(const std::string& s);
|
IFC_PARSE_API Enum FromString(const std::string& s);
|
||||||
IFC_PARSE_API std::string ToString(Enum v);
|
IFC_PARSE_API const std::string& ToString(Enum v);
|
||||||
IFC_PARSE_API bool IsSimple(Enum v);
|
IFC_PARSE_API bool IsSimple(Enum v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,9 +128,9 @@ IfcUtil::IfcBaseClass* %(schema_name)s::SchemaEntity(IfcEntityInstanceData* e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Type::ToString(Enum v) {
|
const std::string& Type::ToString(Enum v) {
|
||||||
if (v < 0 || v >= %(max_id)d) throw IfcException("Unable to find find keyword in schema");
|
if (v < 0 || v >= %(max_id)d) throw IfcException("Unable to find find keyword in schema");
|
||||||
const char* names[] = { %(type_name_strings)s };
|
static std::string names[] = { %(type_name_strings)s };
|
||||||
return names[v];
|
return names[v];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -42,7 +42,7 @@ namespace Type {
|
|||||||
} Enum;
|
} Enum;
|
||||||
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
||||||
IFC_PARSE_API Enum FromString(const std::string& s);
|
IFC_PARSE_API Enum FromString(const std::string& s);
|
||||||
IFC_PARSE_API std::string ToString(Enum v);
|
IFC_PARSE_API const std::string& ToString(Enum v);
|
||||||
IFC_PARSE_API bool IsSimple(Enum v);
|
IFC_PARSE_API bool IsSimple(Enum v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -42,7 +42,7 @@ namespace Type {
|
|||||||
} Enum;
|
} Enum;
|
||||||
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
IFC_PARSE_API boost::optional<Enum> Parent(Enum v);
|
||||||
IFC_PARSE_API Enum FromString(const std::string& s);
|
IFC_PARSE_API Enum FromString(const std::string& s);
|
||||||
IFC_PARSE_API std::string ToString(Enum v);
|
IFC_PARSE_API const std::string& ToString(Enum v);
|
||||||
IFC_PARSE_API bool IsSimple(Enum v);
|
IFC_PARSE_API bool IsSimple(Enum v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-1
@@ -39,6 +39,28 @@ public:
|
|||||||
typedef std::map<std::string, IfcSchema::IfcRoot*> entity_by_guid_t;
|
typedef std::map<std::string, IfcSchema::IfcRoot*> entity_by_guid_t;
|
||||||
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
|
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
|
||||||
typedef entity_by_id_t::const_iterator const_iterator;
|
typedef entity_by_id_t::const_iterator const_iterator;
|
||||||
|
|
||||||
|
class type_iterator : public entities_by_type_t::const_iterator {
|
||||||
|
public:
|
||||||
|
type_iterator() : entities_by_type_t::const_iterator() {};
|
||||||
|
|
||||||
|
type_iterator(const entities_by_type_t::const_iterator& it)
|
||||||
|
: entities_by_type_t::const_iterator(it)
|
||||||
|
{};
|
||||||
|
|
||||||
|
entities_by_type_t::key_type const * operator->() const {
|
||||||
|
return &entities_by_type_t::const_iterator::operator->()->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entities_by_type_t::key_type& operator*() const {
|
||||||
|
return entities_by_type_t::const_iterator::operator*().first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& as_string() const {
|
||||||
|
return IfcSchema::Type::ToString(**this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
typedef std::map<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
||||||
|
|
||||||
@@ -46,6 +68,7 @@ private:
|
|||||||
|
|
||||||
entity_by_id_t byid;
|
entity_by_id_t byid;
|
||||||
entities_by_type_t bytype;
|
entities_by_type_t bytype;
|
||||||
|
entities_by_type_t bytype_excl;
|
||||||
entities_by_ref_t byref;
|
entities_by_ref_t byref;
|
||||||
entity_by_guid_t byguid;
|
entity_by_guid_t byguid;
|
||||||
entity_entity_map_t entity_file_map;
|
entity_entity_map_t entity_file_map;
|
||||||
@@ -69,7 +92,13 @@ public:
|
|||||||
/// Returns the last entity in the file, this probably is the entity
|
/// Returns the last entity in the file, this probably is the entity
|
||||||
/// with the highest id (EXPRESS ENTITY_INSTANCE_NAME)
|
/// with the highest id (EXPRESS ENTITY_INSTANCE_NAME)
|
||||||
const_iterator end() const;
|
const_iterator end() const;
|
||||||
|
|
||||||
|
type_iterator types_begin() const;
|
||||||
|
type_iterator types_end() const;
|
||||||
|
|
||||||
|
type_iterator types_incl_super_begin() const;
|
||||||
|
type_iterator types_incl_super_end() const;
|
||||||
|
|
||||||
/// Returns all entities in the file that match the template argument.
|
/// Returns all entities in the file that match the template argument.
|
||||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
@@ -88,6 +117,9 @@ public:
|
|||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
IfcEntityList::ptr entitiesByType(IfcSchema::Type::Enum t);
|
IfcEntityList::ptr entitiesByType(IfcSchema::Type::Enum t);
|
||||||
|
|
||||||
|
/// Returns all entities in the file that match the positional argument.
|
||||||
|
IfcEntityList::ptr entitiesByTypeExclSubtypes(IfcSchema::Type::Enum t);
|
||||||
|
|
||||||
/// Returns all entities in the file that match the positional argument.
|
/// Returns all entities in the file that match the positional argument.
|
||||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
|
|||||||
@@ -1320,6 +1320,16 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IfcSchema::Type::Enum ty = instance->type();
|
IfcSchema::Type::Enum ty = instance->type();
|
||||||
|
|
||||||
|
{
|
||||||
|
IfcEntityList::ptr instances_by_type = entitiesByTypeExclSubtypes(ty);
|
||||||
|
if (!instances_by_type) {
|
||||||
|
instances_by_type = IfcEntityList::ptr(new IfcEntityList());
|
||||||
|
bytype_excl[ty] = instances_by_type;
|
||||||
|
}
|
||||||
|
instances_by_type->push(instance);
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
||||||
if (!instances_by_type) {
|
if (!instances_by_type) {
|
||||||
@@ -1334,7 +1344,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byid.find(current_id) != byid.end()) {
|
if (byid.find(current_id) != byid.end()) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Overwriting instance with name #" << current_id;
|
ss << "Overwriting instance with name #" << current_id;
|
||||||
@@ -1567,6 +1577,16 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
|
|
||||||
// The mapping by entity type is updated.
|
// The mapping by entity type is updated.
|
||||||
IfcSchema::Type::Enum ty = new_entity->type();
|
IfcSchema::Type::Enum ty = new_entity->type();
|
||||||
|
|
||||||
|
{
|
||||||
|
IfcEntityList::ptr instances_by_type = entitiesByTypeExclSubtypes(ty);
|
||||||
|
if (!instances_by_type) {
|
||||||
|
instances_by_type = IfcEntityList::ptr(new IfcEntityList());
|
||||||
|
bytype_excl[ty] = instances_by_type;
|
||||||
|
}
|
||||||
|
instances_by_type->push(new_entity);
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
IfcEntityList::ptr instances_by_type = entitiesByType(ty);
|
||||||
if (!instances_by_type) {
|
if (!instances_by_type) {
|
||||||
@@ -1582,7 +1602,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_id = -1;
|
int new_id = -1;
|
||||||
if (!new_entity->entity->file) {
|
if (!new_entity->entity->file) {
|
||||||
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
|
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
|
||||||
@@ -1720,10 +1740,33 @@ void IfcFile::removeEntity(IfcUtil::IfcBaseClass* entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byid.erase(byid.find(id));
|
byid.erase(byid.find(id));
|
||||||
|
|
||||||
IfcEntityList::ptr instances_of_same_type = entitiesByType(entity->type());
|
|
||||||
instances_of_same_type->remove(entity);
|
|
||||||
|
|
||||||
|
IfcSchema::Type::Enum ty = entity->type();
|
||||||
|
|
||||||
|
{
|
||||||
|
IfcEntityList::ptr instances_of_same_type = entitiesByTypeExclSubtypes(ty);
|
||||||
|
instances_of_same_type->remove(entity);
|
||||||
|
if (instances_of_same_type->size() == 0) {
|
||||||
|
bytype_excl.erase(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
IfcEntityList::ptr instances_of_same_type = entitiesByType(ty);
|
||||||
|
if (instances_of_same_type) {
|
||||||
|
instances_of_same_type->remove(entity);
|
||||||
|
}
|
||||||
|
if (instances_of_same_type->size() == 0) {
|
||||||
|
bytype.erase(ty);
|
||||||
|
}
|
||||||
|
boost::optional<IfcSchema::Type::Enum> pt = IfcSchema::Type::Parent(ty);
|
||||||
|
if (pt) {
|
||||||
|
ty = *pt;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete entity->entity;
|
delete entity->entity;
|
||||||
delete entity;
|
delete entity;
|
||||||
}
|
}
|
||||||
@@ -1733,6 +1776,11 @@ IfcEntityList::ptr IfcFile::entitiesByType(IfcSchema::Type::Enum t) {
|
|||||||
return (it == bytype.end()) ? IfcEntityList::ptr() : it->second;
|
return (it == bytype.end()) ? IfcEntityList::ptr() : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcEntityList::ptr IfcFile::entitiesByTypeExclSubtypes(IfcSchema::Type::Enum t) {
|
||||||
|
entities_by_type_t::const_iterator it = bytype_excl.find(t);
|
||||||
|
return (it == bytype_excl.end()) ? IfcEntityList::ptr() : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
IfcEntityList::ptr IfcFile::entitiesByType(const std::string& t) {
|
IfcEntityList::ptr IfcFile::entitiesByType(const std::string& t) {
|
||||||
return entitiesByType(IfcSchema::Type::FromString(boost::to_upper_copy(t)));
|
return entitiesByType(IfcSchema::Type::FromString(boost::to_upper_copy(t)));
|
||||||
}
|
}
|
||||||
@@ -1787,6 +1835,22 @@ IfcFile::entity_by_id_t::const_iterator IfcFile::end() const {
|
|||||||
return byid.end();
|
return byid.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcFile::type_iterator IfcFile::types_begin() const {
|
||||||
|
return bytype_excl.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcFile::type_iterator IfcFile::types_end() const {
|
||||||
|
return bytype_excl.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcFile::type_iterator IfcFile::types_incl_super_begin() const {
|
||||||
|
return bytype.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcFile::type_iterator IfcFile::types_incl_super_end() const {
|
||||||
|
return bytype.end();
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
|
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
|
||||||
f.header().write(os);
|
f.header().write(os);
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ private:
|
|||||||
%ignore IfcParse::IfcSpfHeader::stream;
|
%ignore IfcParse::IfcSpfHeader::stream;
|
||||||
%ignore IfcParse::HeaderEntity::is;
|
%ignore IfcParse::HeaderEntity::is;
|
||||||
|
|
||||||
|
%ignore IfcParse::IfcFile::type_iterator;
|
||||||
|
|
||||||
%ignore IfcUtil::IfcBaseClass::is;
|
%ignore IfcUtil::IfcBaseClass::is;
|
||||||
|
|
||||||
%rename("by_id") entityById;
|
%rename("by_id") entityById;
|
||||||
@@ -80,6 +82,22 @@ private:
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> types() const {
|
||||||
|
const size_t n = std::distance($self->types_begin(), $self->types_end());
|
||||||
|
std::vector<std::string> ts;
|
||||||
|
ts.reserve(n);
|
||||||
|
std::transform($self->types_begin(), $self->types_end(), std::back_inserter(ts), IfcSchema::Type::ToString);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> types_with_super() const {
|
||||||
|
const size_t n = std::distance($self->types_incl_super_begin(), $self->types_incl_super_end());
|
||||||
|
std::vector<std::string> ts;
|
||||||
|
ts.reserve(n);
|
||||||
|
std::transform($self->types_incl_super_begin(), $self->types_incl_super_end(), std::back_inserter(ts), IfcSchema::Type::ToString);
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
%pythoncode %{
|
%pythoncode %{
|
||||||
if _newclass:
|
if _newclass:
|
||||||
# Hide the getters with read-only property implementations
|
# Hide the getters with read-only property implementations
|
||||||
|
|||||||
@@ -59,6 +59,15 @@ app = f.by_type("IfcApplication")[0]
|
|||||||
assert f2.add(app).get_info(False, True) == app.get_info(False, True)
|
assert f2.add(app).get_info(False, True) == app.get_info(False, True)
|
||||||
assert "Version" in dir(app)
|
assert "Version" in dir(app)
|
||||||
|
|
||||||
|
# Enumeration of entity type names
|
||||||
|
g = ifcopenshell.open()
|
||||||
|
p = g.createIfcCartesianPoint((0.,0.))
|
||||||
|
assert len(g.types()) == 1
|
||||||
|
assert "IfcPoint" in g.types_with_super()
|
||||||
|
g.remove(p)
|
||||||
|
assert len(g.types()) == 0
|
||||||
|
assert len(g.types_with_super()) == 0
|
||||||
|
|
||||||
# Some operations on ifcopenshell.entity_instance
|
# Some operations on ifcopenshell.entity_instance
|
||||||
assert f[22].Id == ''
|
assert f[22].Id == ''
|
||||||
assert f[22].Addresses is None
|
assert f[22].Addresses is None
|
||||||
|
|||||||
Reference in New Issue
Block a user