diff --git a/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi b/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi index 4a9369977e..9b35f8b0cd 100644 --- a/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi +++ b/src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.pyi @@ -91,20 +91,19 @@ SHARED_PTR_DISOWN: Any cvar: Any -class IfcSpfHeader: +class spf_header: """ IFC Header definition: https://standards.buildingsmart.org/documents/Implementation/ImplementationGuide_IFCHeaderData_Version_1.0.2.pdf """ - def __init__(self, *args): ... - def file(self, *args): ... - def file_description_py(self): ... - def file_name_py(self): ... - def file_schema_py(self): ... - def read(self): ... - def tryRead(self): ... - def write(self, out): ... + def __init__(self, file: file | None = None, logger: logger | None = None): ... + @property + def file_description(self) -> entity_instance: ... + @property + def file_name(self) -> entity_instance: ... + @property + def file_schema(self) -> entity_instance: ... class BRep(Representation): def __init__(self, settings, entity, id, shapes): ... @@ -149,6 +148,7 @@ class ConversionResultShape: def add(self, arg2): ... def area(self): ... def axis(self): ... + def backend_id(self) -> str: ... def bounding_box(self, *args): ... def box(self): ... def concat(self, arg2): ... @@ -269,25 +269,6 @@ class GeometrySerializer: def write(self, *args): ... def writeHeader(self): ... -class IfcBaseEntity(entity_instance): - def __init__(self, *args, **kwargs): ... - def declaration(self): ... - def get(self, name): ... - def get_inverse(self, name): ... - def populate_derived(self): ... - def set_id(self, i): ... - -class IfcBaseType(entity_instance): - def __init__(self, *args, **kwargs): ... - def declaration(self): ... - -class IfcEntityInstanceData: - def __init__(self, *args, **kwargs): ... - -class IfcLateBoundEntity(IfcBaseEntity): - def __init__(self, decl, data): ... - def declaration(self): ... - class instance_streamer: def __init__(self, *args): ... def bypass_types(self, type_names): ... @@ -745,6 +726,7 @@ class entity(declaration): """Return a tuple of booleans indicating whether each direct attribute is derived.""" ... + def inverse_attributes(self) -> tuple[inverse_attribute, ...]: ... def is_abstract(self) -> bool: ... def set_attributes(self, attributes, derived): ... def set_inverse_attributes(self, inverse_attributes): ... @@ -753,26 +735,40 @@ class entity(declaration): def supertype(self) -> Union[entity, None]: ... class entity_instance(entity_instance_mixin): - def __init__(self, *args, **kwargs): ... - file: ifcopenshell.file - """Reference to IFC file to prevent it's garbage collection, if entity is still used.""" - - file_: Any - id_: Any - def data(self, *args): ... + def __init__(self, *args): ... @property def declaration(self) -> declaration: ... - def file_pointer(self): - """Internal IfcFile pointer address. + @property + def file(self) -> file: ... - Same as ``file.file_pointer``). - """ - ... - - def get_argument(self, *args): ... - def get_argument_index(self, a): ... - def get_argument_name(self, i): ... - def get_argument_type(self, i): ... + def get_argument(self, *args: int | str) -> Any: ... + def get_argument_index(self, a: str) -> int: ... + def attribute_name(self, i: int) -> str: ... + def attribute_type( + self, *args: int | str + ) -> Literal[ + "NULL", + "DERIVED", + "INT", + "BOOL", + "LOGICAL", + "DOUBLE", + "STRING", + "BINARY", + "ENUMERATION", + "ENTITY INSTANCE", + "EMPTY AGGREGATE", + "AGGREGATE OF INT", + "AGGREGATE OF DOUBLE", + "AGGREGATE OF STRING", + "AGGREGATE OF BINARY", + "AGGREGATE OF ENTITY INSTANCE", + "AGGREGATE OF EMPTY AGGREGATE", + "AGGREGATE OF AGGREGATE OF INT", + "AGGREGATE OF AGGREGATE OF DOUBLE", + "AGGREGATE OF AGGREGATE OF ENTITY INSTANCE", + "UNKNOWN", + ]: ... def get_attribute_category(self, name: str) -> Literal[0, 1, 2]: """Get attribute category id. @@ -783,41 +779,27 @@ class entity_instance(entity_instance_mixin): """ ... - def get_attribute_names(self): ... - def get_attribute_value(self, index): ... - def get_inverse(self, a): ... - def get_inverse_attribute_names(self): ... + def get_attribute_names(self) -> tuple[str, ...]: ... + def get_attribute_value(self, attribute_index: int) -> Any: ... + def _get_inverse(self, *args: entity_instance | str) -> tuple[entity_instance, ...]: ... + def get_inverse_attribute_names(self) -> tuple[str, ...]: ... def id(self) -> int: ... def identity(self) -> int: """Entity instance identity, unique across all opened IFC files during current session.""" ... def is_a(self, *args): ... - def setArgumentAsAggregateOfAggregateOfDouble(self, i, v): ... - def setArgumentAsAggregateOfAggregateOfEntityInstance(self, i, v): ... - def setArgumentAsAggregateOfAggregateOfInt(self, i, v): ... - def setArgumentAsAggregateOfDouble(self, i, v): ... - def setArgumentAsAggregateOfEntityInstance(self, i, v): ... - def setArgumentAsAggregateOfInt(self, i, v): ... - def setArgumentAsAggregateOfString(self, i, v): ... - def setArgumentAsBool(self, i, v): ... - def setArgumentAsDouble(self, i, v): ... - def setArgumentAsEntityInstance(self, i, v): ... - def setArgumentAsInt(self, i, v): ... - def setArgumentAsLogical(self, i, v): ... - def setArgumentAsNull(self, i): ... - def setArgumentAsString(self, i, a): ... def set_attribute_value(self, *args): ... - def toString(self, arg2, upper=False): ... - def to_string(self, valid_spf=True): ... - def unset_attribute_value(self, i): ... + def set_attribute_value_py(self, i: int, value: Any) -> None: ... + def to_string(self, *args) -> str | None: ... + def unset_attribute_value(self, attribute_index: int) -> None: ... class enumeration_type(declaration): def __init__(self, name, index_in_schema, enumeration_items): ... def argument_types(self) -> tuple[str, ...]: ... def as_enumeration_type(self) -> enumeration_type: ... def enumeration_items(self) -> tuple[str, ...]: ... - def lookup_enum_offset(self, string: str) -> int: + def lookup_enum_offset(self, value_name: str) -> int: """Get index of the string in enum.""" ... @@ -847,10 +829,9 @@ class face: def print_impl(self, o, indent): ... class file(file_mixin): - def FreshId(self): ... + def fresh_id(self) -> int: ... def __init__(self, *args): ... - def add(self, entity: entity_instance, id: int = -1) -> entity_instance: ... - def addEntities(self, entities): ... + def _add(self, entity: entity_instance, id: int = -1) -> entity_instance: ... def add_type_ref(self, new_entity): ... def batch(self) -> None: """Enable batch mode. @@ -874,31 +855,22 @@ class file(file_mixin): """Exit batch mode.""" ... - def build_inverses(self): ... - def build_inverses_(self, arg2): ... - def by_guid(self, guid: str) -> entity_instance: ... - def by_id(self, id: int) -> entity_instance: ... - def by_type(self, *args): ... - def by_type_excl_subtypes(self, *args): ... + def by_guid(self, global_id: str) -> entity_instance: ... + def by_id(self, instance_id: int) -> entity_instance: ... + def _by_type(self, *args: declaration | str) -> tuple[entity_instance, ...]: ... + def _by_type_excl_subtypes(self, *args: declaration | str) -> tuple[entity_instance, ...]: ... def bypass_type(self, type_name: str) -> None: ... - calculate_unit_factors: bool - check_existance_before_adding: bool - def create(self, decl): ... + def create(self, *args) -> entity_instance: ... @staticmethod - def createTimestamp(): ... + def create_timestamp() -> str: ... def entity_names(self) -> tuple[int, ...]: """Get a tuple of step ids present in the file.""" ... - def file_pointer(self) -> int: - """Internal IfcFile pointer address. - - Same as ``int(self.this)``. - """ - ... - + @staticmethod + def from_string(s: str) -> "file": ... def get_inverses_by_declaration( - self, instance_id: int, type: declaration, attribute_index: int + self, instance_id: int, declaration: declaration, attribute_index: int ) -> tuple[entity_instance, ...]: """Get instance inverses of the particular type defined by ``declaration``. @@ -909,40 +881,37 @@ class file(file_mixin): """ ... - def getMaxId(self): ... - def get_total_inverses_by_id(self, instance_id: int) -> int: ... - def getUnit(self, unit_type): ... - def get_inverse(self, e: entity_instance) -> tuple[entity_instance, ...]: ... - def get_inverse_indices(self, *args: Union[entity_instance, int]) -> tuple[int, ...]: + def get_max_id(self) -> int: ... + def get_inverse_indices_by_id(self, instance_id: int) -> tuple[int, ...]: ... + def _get_inverse(self, e: entity_instance) -> tuple[entity_instance, ...]: ... + def _get_inverse_indices(self, *args: Union[entity_instance, int]) -> tuple[int, ...]: """Get the attribute indices for each inverse from `get_inverse`, that reference the provided entity.. :param args: entity or it's id. Maximum 1 entity at the time. """ ... - def get_total_inverses(self, e: entity_instance) -> int: ... + def get_total_inverses(self, *args: entity_instance | int) -> int: ... def good(self): ... - def header(self, *args) -> IfcSpfHeader: - """Internal IfcSpfHeader instance, always prefer ``ifcopenshell.file.header`` instead.""" + @property + def header(self) -> spf_header: ... def ifcroot_type(self) -> entity: ... def initialize(self, *args): ... - instantiate_typed_instances: bool def key_value_store_iter(self, prefix): ... def key_value_store_query(self, key): ... - def process_deletion_inverse(self, inst): ... def recalculate_id_counter(self): ... - def remove(self, entity: entity_instance) -> None: ... + def _remove(self, entity: entity_instance) -> None: ... def remove_type_ref(self, new_entity): ... def reset_identity_cache(self): ... @property - def schema(self): ... + def schema_identifier(self) -> str: ... def storage_mode(self): ... def to_string(self): ... @staticmethod - def traverse(instance: entity_instance, max_level: int = -1) -> tuple[entity_instance, ...]: ... + def _traverse(instance: entity_instance, max_level: int = -1) -> tuple[entity_instance, ...]: ... @staticmethod - def traverse_breadth_first(instance: entity_instance, max_level: int = -1) -> tuple[entity_instance, ...]: ... + def _traverse_breadth_first(instance: entity_instance, max_level: int = -1) -> tuple[entity_instance, ...]: ... def types(self) -> tuple[str, ...]: """Return a tuple of classes present in the file. @@ -950,7 +919,7 @@ class file(file_mixin): """ ... - def write(self, fn): ... + def _write(self, fn: str) -> None: ... class file_open_status: SUCCESS: int @@ -1005,6 +974,7 @@ class geometry_conversion_result: products: Any products_2: Any representation: Any + def is_parallel(self) -> bool: ... class gradient_function(function_item): def __init__(self, *args): ... @@ -1130,7 +1100,7 @@ class loft: class loop: closed: Any external: Any - function_item: Any + fi: Any tags: Any def calc_hash(self): ... def calculate_linear_edge_curves(self): ... @@ -1280,7 +1250,7 @@ class revolve(sweep): def matrix(self): ... class schema_definition: - def __init__(self, name, declarations, factory): ... + def __init__(self, name: str, declarations: Sequence[declaration]): ... def declaration_by_name(self, *args: str) -> declaration: """ :return: ``declaration`` but upcasted to the most advanced available type @@ -1298,7 +1268,6 @@ class schema_definition: def enumeration_types(self) -> tuple[enumeration_type, ...]: ... def select_types(self) -> tuple[select_type, ...]: ... def type_declarations(self) -> tuple[type_declaration, ...]: ... - def instantiate(self, decl, data): ... def name(self) -> str: ... class select_type(declaration): @@ -1652,7 +1621,7 @@ def nary_union(sequence): ... def new_IfcBaseClass(file: file, name: str) -> entity_instance: ... def open(fn: str, readonly: bool = False, logger=None) -> file: ... def polygons_to_svg(*args): ... -def read(data): ... +def read(data: str) -> file: ... def register_schema(schema: schema_definition) -> None: ... def schema_by_name(schema_name: str) -> schema_definition: ... def schema_names() -> tuple[str, ...]: ... diff --git a/src/ifcparse/parse.cpp b/src/ifcparse/parse.cpp index 248e4791bc..9b80731992 100644 --- a/src/ifcparse/parse.cpp +++ b/src/ifcparse/parse.cpp @@ -1622,7 +1622,7 @@ file::file(const std::string& fn, bool mmap, ::logger& log) , schema_(nullptr) , ifcroot_type_(nullptr) , max_id_(0) - , header_(new spf_header(this, logger_.get())) { + , header_(new spf_header(this, &logger_.get())) { initialize(fn, mmap); } @@ -1650,7 +1650,7 @@ bool ifcopenshell::file::initialize(const std::string& fn, bool mmap) { #endif file::file(const uninitialized_tag&, ::logger& log) - : good_(file_open_status::UNKNOWN), logger_(log), schema_(nullptr), ifcroot_type_(nullptr), max_id_(0), header_(new ifcopenshell::spf_header(this, logger_.get())) {} + : good_(file_open_status::UNKNOWN), logger_(log), schema_(nullptr), ifcroot_type_(nullptr), max_id_(0), header_(new ifcopenshell::spf_header(this, &logger_.get())) {} bool ifcopenshell::file::initialize(const std::string& path, filetype ty, bool readonly) { if (ty == FT_AUTODETECT) { @@ -1707,7 +1707,7 @@ file::file(const std::string& path, filetype ty, bool readonly, ::logger& log) , schema_(nullptr) , ifcroot_type_(nullptr) , max_id_(0) - , header_(new spf_header(this, logger_.get())) + , header_(new spf_header(this, &logger_.get())) { initialize(path, ty, readonly); } @@ -1717,7 +1717,7 @@ file::file(std::istream& stream, int length, ::logger& log) , schema_(nullptr) , ifcroot_type_(nullptr) , max_id_(0) - , header_(new ifcopenshell::spf_header(this, logger_.get())) + , header_(new ifcopenshell::spf_header(this, &logger_.get())) { file_reader s(caller_fed_tag{}); @@ -1741,7 +1741,7 @@ file::file(void* data, int length, ::logger& log) , schema_(nullptr) , ifcroot_type_(nullptr) , max_id_(0) - , header_(new ifcopenshell::spf_header(this, logger_.get())) + , header_(new ifcopenshell::spf_header(this, &logger_.get())) { file_reader s(std::string((char*)data, length), caller_fed_tag{}); @@ -1783,7 +1783,7 @@ file::file(const ifcopenshell::schema_definition* schema, filetype ty, const std } else { throw std::runtime_error("Unsupported file format"); } - header_.reset(new spf_header(this, logger_.get())); + header_.reset(new spf_header(this, &logger_.get())); set_default_header_values(); } @@ -1872,7 +1872,7 @@ spf_header& ifcopenshell::instance_streamer::ensure_header() { header_ = &owner_->header(); header_->owner_file(owner_); } else { - owned_header_ = std::make_unique(owner_, logger_.get()); + owned_header_ = std::make_unique(owner_, &logger_.get()); header_ = owned_header_.get(); } diff --git a/src/ifcparse/spf_header.cpp b/src/ifcparse/spf_header.cpp index 3405aefb14..d685fe3e1d 100644 --- a/src/ifcparse/spf_header.cpp +++ b/src/ifcparse/spf_header.cpp @@ -1,6 +1,7 @@ #include "spf_header.h" #include "file.h" +#include "logger.h" static const char* const ISO_10303_21 = "ISO-10303-21"; static const char* const HEADER = "HEADER"; @@ -26,9 +27,9 @@ shared_pointer_type make_header_entity(ifcopenshell::file* file, const ifcopensh } // namespace -ifcopenshell::spf_header::spf_header(ifcopenshell::file* file, ::logger& logger) +ifcopenshell::spf_header::spf_header(ifcopenshell::file* file, ::logger* logger) : file_(file) - , logger_(logger) { + , logger_(logger_or_root(logger)) { Header_section_schema::get_schema(); header_entities_[0] = make_header_entity(file_, Header_section_schema::file_description::Class(), logger_); diff --git a/src/ifcparse/spf_header.h b/src/ifcparse/spf_header.h index b32bc63fd6..5bef3dbe4f 100644 --- a/src/ifcparse/spf_header.h +++ b/src/ifcparse/spf_header.h @@ -37,7 +37,7 @@ class IFC_PARSE_API spf_header { std::array header_entities_; public: - explicit spf_header(ifcopenshell::file* file = nullptr, ::logger& logger = ::logger::root()); + explicit spf_header(ifcopenshell::file* file = nullptr, ::logger* logger = nullptr); ~spf_header(); void write(std::ostream& stream) const; diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 003a839b94..d80ef5c7d7 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -20,6 +20,13 @@ %ignore ifcopenshell::file::register_inverse; %ignore ifcopenshell::file::unregister_inverse; %ignore ifcopenshell::file::schema; +%ignore ifcopenshell::file::logger; +%ignore ifcopenshell::file::process_deletion_inverse; +%ignore ifcopenshell::file::build_inverses_; +%ignore ifcopenshell::file::get_unit; +%ignore ifcopenshell::file::build_inverses; +%ignore ifcopenshell::file::check_existance_before_adding; +%ignore ifcopenshell::file::calculate_unit_factors; %ignore ifcopenshell::file::begin; %ignore ifcopenshell::file::end; %ignore ifcopenshell::file::types_begin; @@ -67,6 +74,10 @@ %ignore ifcopenshell::spf_header::set_file_name; %ignore ifcopenshell::spf_header::set_file_schema; +%ignore ifcopenshell::spf_header::logger; +%ignore ifcopenshell::spf_header::owner_file; +%ignore ifcopenshell::spf_header::write; + %ignore ifcopenshell::HeaderEntity::is; %ignore ifcopenshell::file::type_iterator; @@ -991,9 +1002,9 @@ static bool express_Base_equals(const express::Base* self, const express::Base* %include "../ifcparse/spf_header.h" %pythoncode %{ -from .file import file_mixin as _file_mixin_base +from .file import file_mixin as file_mixin %} -%feature("python:abc", "_file_mixin_base") ifcopenshell::file; +%feature("python:abc", "file_mixin") ifcopenshell::file; %include "../ifcparse/file.h" %template(instance_streamer) ifcopenshell::instance_streamer>; @@ -1001,9 +1012,9 @@ from .file import file_mixin as _file_mixin_base %include "../ifcparse/file_open_status.h" %pythoncode %{ -from .entity_instance import entity_instance_mixin as _entity_instance_mixin_base +from .entity_instance import entity_instance_mixin %} -%feature("python:abc", "_entity_instance_mixin_base") express::Base; +%feature("python:abc", "entity_instance_mixin") express::Base; %include "../ifcparse/express.h" diff --git a/src/ifcwrap/IfcPython.i b/src/ifcwrap/IfcPython.i index 1270373864..a86a5faee0 100644 --- a/src/ifcwrap/IfcPython.i +++ b/src/ifcwrap/IfcPython.i @@ -76,6 +76,7 @@ // Not relevant for python usage %ignore express::Base::data; +%ignore express::Base::data_weak; %ignore *::references_to_resolve; // SVG serializer internal