Skip to content

Commit cef1c86

Browse files
Moultaothms
authored andcommitted
Experimental get_inverse_cardinality proposal. See IfcOpenShell#1904.
1 parent d1caa32 commit cef1c86

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

src/ifcopenshell-python/ifcopenshell/file.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,16 @@ def get_inverse(self, inst, allow_duplicate=False):
391391
return inverses
392392
return set(inverses)
393393

394+
def get_inverse_cardinality(self, inst):
395+
"""Returns the number of entities that reference this entity
396+
397+
:param inst: The entity instance to get inverse relationships
398+
:type inst: ifcopenshell.entity_instance.entity_instance
399+
:returns: 0 if no references, 1 if one reference, or 2 if more than one reference
400+
:rtype: int
401+
"""
402+
return self.wrapped_data.get_inverse_cardinality(inst.wrapped_data)
403+
394404
def remove(self, inst):
395405
"""Deletes an IFC object in the file.
396406

src/ifcparse/IfcFile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class IFC_PARSE_API IfcFile {
249249
aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level=-1);
250250

251251
aggregate_of_instance::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
252+
int getInverseCardinality(int instance_id);
252253

253254
template <class T>
254255
typename T::list::ptr getInverse(int instance_id, int attribute_index) {

src/ifcparse/IfcParse.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,25 @@ aggregate_of_instance::ptr IfcFile::getInverse(int instance_id, const IfcParse::
23872387
return return_value;
23882388
}
23892389

2390+
2391+
int IfcFile::getInverseCardinality(int instance_id) {
2392+
auto lower = byref_excl.lower_bound({ instance_id,-1,-1 });
2393+
auto upper = byref_excl.upper_bound({ instance_id, std::numeric_limits<int>::max(), std::numeric_limits<int>::max() });
2394+
2395+
int total_references = 0;
2396+
for (auto it = lower; it != upper; it++) {
2397+
for (auto& i : it->second) {
2398+
total_references++;
2399+
if (total_references > 1) {
2400+
return total_references;
2401+
}
2402+
}
2403+
}
2404+
2405+
return total_references;
2406+
}
2407+
2408+
23902409
void IfcFile::setDefaultHeaderValues() {
23912410
const std::string empty_string = "";
23922411
std::vector<std::string> file_description, schema_identifiers, empty_vector;

src/ifcwrap/IfcParseWrapper.i

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
8888
aggregate_of_instance::ptr get_inverse(IfcUtil::IfcBaseClass* e) {
8989
return $self->getInverse(e->data().id(), 0, -1);
9090
}
91+
int get_inverse_cardinality(IfcUtil::IfcBaseClass* e) {
92+
return $self->getInverseCardinality(e->data().id());
93+
}
9194

9295
void write(const std::string& fn) {
9396
std::ofstream f(IfcUtil::path::from_utf8(fn).c_str());

0 commit comments

Comments
 (0)