mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 16:01:36 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92f9bd5938 | |||
| 71a598e63a | |||
| 3d8115ebc5 | |||
| b5a0f1fc74 | |||
| 25441bd816 | |||
| 65811ac7c9 | |||
| d9d1824886 | |||
| 16e5f18553 | |||
| b7a9b7bc5a | |||
| e14397058d | |||
| f0117c60b3 | |||
| 0e5223a30d | |||
| bc41ff78f4 | |||
| 9123d8c183 | |||
| ffd939508c | |||
| 9213b31235 | |||
| 2155e3206f | |||
| 9e0c6cf524 | |||
| d5dc069b2f | |||
| 821cf7b671 |
@@ -55,11 +55,17 @@ jobs:
|
||||
black --diff --check . | black-codeclimate | python .github/workflows/black_to_github_annotations.py
|
||||
continue-on-error: true
|
||||
|
||||
- name: ty check
|
||||
id: ty
|
||||
run: |
|
||||
poe ty-venv
|
||||
poe ty
|
||||
- name: ty check (venv setup)
|
||||
run: poe ty-venv
|
||||
|
||||
- name: ty check (bonsai)
|
||||
id: ty-bonsai
|
||||
run: poe ty-bonsai
|
||||
continue-on-error: true
|
||||
|
||||
- name: ty check (ios)
|
||||
id: ty-ios
|
||||
run: poe ty-ios
|
||||
continue-on-error: true
|
||||
|
||||
- name: Ruff check
|
||||
@@ -109,7 +115,10 @@ jobs:
|
||||
if [ "${{ steps.ruff.outcome }}" != "success" ]; then
|
||||
echo "::error::Ruff check failed, see Summary or 'ruff' step for the details." && ERROR=1
|
||||
fi
|
||||
if [ "${{ steps.ty.outcome }}" != "success" ]; then
|
||||
echo "::error::ty check failed, see 'ty check' step for the details." && ERROR=1
|
||||
if [ "${{ steps.ty-bonsai.outcome }}" != "success" ]; then
|
||||
echo "::error::ty check (bonsai) failed, see 'ty check (bonsai)' step for the details." && ERROR=1
|
||||
fi
|
||||
if [ "${{ steps.ty-ios.outcome }}" != "success" ]; then
|
||||
echo "::error::ty check (ios) failed, see 'ty check (ios)' step for the details." && ERROR=1
|
||||
fi
|
||||
exit $ERROR
|
||||
|
||||
@@ -843,7 +843,6 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
settings = ifcopenshell.geom.settings()
|
||||
shape = ifcopenshell.geom.create_shape(settings, opening)
|
||||
mat = Matrix(ifcopenshell.util.shape.get_shape_matrix(shape))
|
||||
mat.translation = (0, 0, 0)
|
||||
opening_bm = bmesh.new()
|
||||
verts = ifcopenshell.util.shape.get_vertices(shape.geometry)
|
||||
for vert in verts:
|
||||
|
||||
@@ -581,7 +581,11 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if has_openings and not self.apply_openings:
|
||||
# Meshlike things with openings can only be updated without openings applied.
|
||||
if self.from_ui:
|
||||
self.report({"ERROR"}, f"Object '{obj.name}' has openings - representation cannot be updated.")
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
f"Object '{obj.name}' has openings. "
|
||||
"ALT+click the button to bake the openings into the new representation.",
|
||||
)
|
||||
return
|
||||
|
||||
if not product.is_a("IfcGridAxis"):
|
||||
|
||||
@@ -27,6 +27,7 @@ import ifcopenshell.api.material
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.schema
|
||||
import ifcopenshell.util.shape_builder
|
||||
import ifcopenshell.util.type
|
||||
@@ -129,13 +130,25 @@ class ReassignClass(bpy.types.Operator, tool.Ifc.Operator):
|
||||
same_ifc_product = element.is_a(ifc_product)
|
||||
|
||||
if not same_ifc_product:
|
||||
if not (element.is_a("IfcElement") and ifc_product == "IfcElementType") and not (
|
||||
element.is_a("IfcElementType") and ifc_product == "IfcElement"
|
||||
):
|
||||
self.report(
|
||||
{"ERROR"}, f"Not supported class reassignment for object '{obj.name}' -> {ifc_product}."
|
||||
# A spatial element (e.g. IfcSite) anchors the containment
|
||||
# hierarchy, so only allow reassigning it to another family when
|
||||
# it actually carries geometry - i.e. it's a real modelled thing
|
||||
# (a bench dropped onto IfcSite -> IfcFurniture) rather than an
|
||||
# empty spatial container we'd be turning into a loose element.
|
||||
# IfcSpatialStructureElement covers IFC2X3, which has no
|
||||
# IfcSpatialElement supertype.
|
||||
is_spatial = element.is_a("IfcSpatialElement") or element.is_a("IfcSpatialStructureElement")
|
||||
if is_spatial:
|
||||
has_geometry = (
|
||||
next(ifcopenshell.util.representation.get_representations_iter(element), None) is not None
|
||||
)
|
||||
return {"CANCELLED"}
|
||||
if not has_geometry:
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
f"Cannot reassign '{obj.name}' ({element.is_a()}) to {ifc_product}: "
|
||||
"a spatial element can only be reassigned to another class when it has geometry.",
|
||||
)
|
||||
return {"CANCELLED"}
|
||||
|
||||
props = tool.Blender.get_object_bim_props(obj)
|
||||
props.is_reassigning_class = False
|
||||
|
||||
@@ -675,7 +675,7 @@ int main(int argc, char** argv) {
|
||||
time_t start, end;
|
||||
time(&start);
|
||||
if (output_extension == XML) {
|
||||
XmlSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename), logger);
|
||||
XmlSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename), &logger);
|
||||
logger.Status("Writing XML output...");
|
||||
s.finalize();
|
||||
} else {
|
||||
@@ -834,14 +834,14 @@ int main(int argc, char** argv) {
|
||||
if (output_extension == OBJ) {
|
||||
// Do not use temp file for MTL as it's such a small file.
|
||||
const path_t mtl_filename = change_extension(output_filename, MTL);
|
||||
serializer = boost::make_shared<WaveFrontOBJSerializer>(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), geometry_settings, serializer_settings, logger);
|
||||
serializer = boost::make_shared<WaveFrontOBJSerializer>(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), geometry_settings, serializer_settings, &logger);
|
||||
#ifdef WITH_OPENCOLLADA
|
||||
} else if (output_extension == DAE) {
|
||||
serializer = boost::make_shared<ColladaSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger);
|
||||
serializer = boost::make_shared<ColladaSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, &logger);
|
||||
#endif
|
||||
#ifdef WITH_GLTF
|
||||
} else if (output_extension == GLB) {
|
||||
serializer = boost::make_shared<GltfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger);
|
||||
serializer = boost::make_shared<GltfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, &logger);
|
||||
#endif
|
||||
#ifdef WITH_USD
|
||||
} else if (output_extension == USD || output_extension == USDA || output_extension == USDC) {
|
||||
@@ -858,15 +858,15 @@ int main(int argc, char** argv) {
|
||||
serializer = boost::make_shared<IgesSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger);
|
||||
} else if (output_extension == SVG) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
serializer = boost::make_shared<SvgSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger);
|
||||
serializer = boost::make_shared<SvgSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, &logger);
|
||||
#ifdef WITH_HDF5
|
||||
} else if (output_extension == HDF) {
|
||||
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, false, logger);
|
||||
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, false, &logger);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
} else if (output_extension == TTL) {
|
||||
serializer = boost::make_shared<TtlWktSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger);
|
||||
serializer = boost::make_shared<TtlWktSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, &logger);
|
||||
} else {
|
||||
cerr_ << "[Error] Unknown output filename extension '" << output_extension << "'\n";
|
||||
write_log(!quiet);
|
||||
@@ -1011,7 +1011,7 @@ int main(int argc, char** argv) {
|
||||
if (!vmap.count("cache-file")) {
|
||||
cache_file = input_filename + CACHE + HDF;
|
||||
}
|
||||
cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), geometry_settings, serializer_settings, false, logger));
|
||||
cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), geometry_settings, serializer_settings, false, &logger));
|
||||
context_iterator->set_cache(cache.get());
|
||||
}
|
||||
#endif
|
||||
@@ -1290,7 +1290,7 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
|
||||
|
||||
#ifdef WITH_IFCXML
|
||||
if (boost::ends_with(boost::to_lower_copy(filename), ".ifcxml")) {
|
||||
ifc_file = IfcParse::parse_ifcxml(filename, logger);
|
||||
ifc_file = IfcParse::parse_ifcxml(filename, &logger);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ PLATFORMTAG:=win_amd64
|
||||
endif
|
||||
|
||||
BINARY_VERSION:=0.8.6
|
||||
BUILD_COMMIT:=3e7b739
|
||||
BUILD_COMMIT:=821cf7b
|
||||
IOS_URL:=https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-$(PYNUMBER)-v$(BINARY_VERSION)-$(BUILD_COMMIT)-$(PLATFORM).zip
|
||||
IFCCONVERT_URL:=https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v$(BINARY_VERSION)-$(BUILD_COMMIT)-$(PLATFORM).zip
|
||||
|
||||
|
||||
@@ -97,7 +97,19 @@ from .file import file as _file
|
||||
from .sql import sqlite, sqlite_entity
|
||||
|
||||
get_log = ifcopenshell_wrapper.get_log
|
||||
logger = getattr(ifcopenshell_wrapper, "logger", None)
|
||||
logger = ifcopenshell_wrapper.logger if hasattr(ifcopenshell_wrapper, "logger") else None
|
||||
if hasattr(ifcopenshell_wrapper, "logger_or_root"):
|
||||
logger_or_root = ifcopenshell_wrapper.logger_or_root
|
||||
else:
|
||||
|
||||
def logger_or_root(_logger: ifcopenshell_wrapper.logger | None) -> None:
|
||||
return None
|
||||
|
||||
|
||||
# TODO: drop this function and all callsites after we migrate to the new build.
|
||||
def optional_logger_args(logger: ifcopenshell_wrapper.logger | None) -> tuple[logger] | tuple[()]:
|
||||
return (logger,) if logger is not None else ()
|
||||
|
||||
|
||||
# explicitly specify available imported symbols
|
||||
# (it's a requirement for a typed library)
|
||||
@@ -194,10 +206,9 @@ def open(
|
||||
raise FileNotFoundError(f"Path does not exist: '{path}'.")
|
||||
if format is None:
|
||||
format = guess_format(path)
|
||||
if logger is None and (logger_type := getattr(ifcopenshell_wrapper, "logger", None)):
|
||||
logger = logger_type.Root()
|
||||
logger = logger_or_root(logger)
|
||||
if format == ".ifcXML":
|
||||
f = ifcopenshell_wrapper.parse_ifcxml(str(path.absolute()), *((logger,) if logger is not None else ()))
|
||||
f = ifcopenshell_wrapper.parse_ifcxml(str(path.absolute()), *optional_logger_args(logger))
|
||||
if f:
|
||||
return file(f)
|
||||
raise OSError(f"Failed to parse .ifcXML file from {path}")
|
||||
@@ -214,11 +225,9 @@ def open(
|
||||
if should_stream:
|
||||
return stream(path)
|
||||
if readonly: # Temporary conditional see #7131. Remove once newer builds don't segfault on Linux.
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), readonly, *((logger,) if logger is not None else ()))
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), readonly, *optional_logger_args(logger))
|
||||
elif bypass_types:
|
||||
f = ifcopenshell_wrapper.file(
|
||||
ifcopenshell_wrapper.uninitialized_tag(), *((logger,) if logger is not None else ())
|
||||
)
|
||||
f = ifcopenshell_wrapper.file(ifcopenshell_wrapper.uninitialized_tag(), *optional_logger_args(logger))
|
||||
for ty in bypass_types:
|
||||
f.bypass_type(ty)
|
||||
if mmap:
|
||||
@@ -233,7 +242,7 @@ def open(
|
||||
kwargs["logger"] = logger
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), **kwargs)
|
||||
else:
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), False, *((logger,) if logger is not None else ()))
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), False, *optional_logger_args(logger))
|
||||
return file(f)
|
||||
|
||||
|
||||
@@ -305,12 +314,13 @@ def schema_by_name(
|
||||
you are testing non-ISO IFC releases.
|
||||
:return: Schema definition object.
|
||||
"""
|
||||
import ifcopenshell.util.schema
|
||||
|
||||
assert schema_version or schema, "Either schema or schema_version must be specified."
|
||||
if schema_version:
|
||||
prefixes = ("IFC", "X", "_ADD", "_TC")
|
||||
schema = "".join("".join(map(str, t)) if t[1] else "" for t in zip(prefixes, schema_version))
|
||||
schema = ifcopenshell.util.schema.get_schema_name_from_version(schema_version)
|
||||
else:
|
||||
schema = {"IFC4X3": "IFC4X3_ADD2"}.get(schema, schema)
|
||||
schema = ifcopenshell.util.schema.get_schema_identifier(schema)
|
||||
return ifcopenshell_wrapper.schema_by_name(schema)
|
||||
|
||||
|
||||
|
||||
@@ -107,8 +107,7 @@ def main(
|
||||
progress_function: Callable = DO_NOTHING,
|
||||
logger=None,
|
||||
):
|
||||
if logger is None and ifcopenshell.logger is not None:
|
||||
logger = ifcopenshell.logger.Root()
|
||||
logger = ifcopenshell.logger_or_root(logger)
|
||||
|
||||
def by_guid(g):
|
||||
for f in files:
|
||||
|
||||
@@ -23,7 +23,6 @@ import numbers
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import types
|
||||
import weakref
|
||||
import zipfile
|
||||
from collections.abc import Callable, Generator
|
||||
@@ -244,19 +243,14 @@ file_dict: dict[int, tuple[weakref.ReferenceType[file], int]] = {}
|
||||
"""Mapping of internal IfcFile pointer address to existing ``ifcopenshell.file``
|
||||
and the timestamp when it was created.
|
||||
|
||||
Needed only to quickly access related from ``entity_instance`` it's ``file``.
|
||||
Needed only to quickly access from ``entity_instance`` its ``file``.
|
||||
"""
|
||||
|
||||
READ_ERROR = ifcopenshell_wrapper.file_open_status.READ_ERROR
|
||||
NO_HEADER = ifcopenshell_wrapper.file_open_status.NO_HEADER
|
||||
UNSUPPORTED_SCHEMA = ifcopenshell_wrapper.file_open_status.UNSUPPORTED_SCHEMA
|
||||
INVALID_SYNTAX = ifcopenshell_wrapper.file_open_status.INVALID_SYNTAX
|
||||
|
||||
# TODO: Workaround for old builds, remove after build stabilizes.
|
||||
try:
|
||||
UNKNOWN = ifcopenshell_wrapper.file_open_status.UNKNOWN
|
||||
except:
|
||||
UNKNOWN = 5 # Workaround
|
||||
UNKNOWN = ifcopenshell_wrapper.file_open_status.UNKNOWN
|
||||
|
||||
import struct
|
||||
|
||||
@@ -594,11 +588,12 @@ class file:
|
||||
# A poweruser testing out a particular version of IFC4X3
|
||||
model = ifcopenshell.file(schema_version=(4, 3, 0, 1))
|
||||
"""
|
||||
import ifcopenshell.util.schema
|
||||
|
||||
if schema_version:
|
||||
prefixes = ("IFC", "X", "_ADD", "_TC")
|
||||
schema = "".join("".join(map(str, t)) if t[1] else "" for t in zip(prefixes, schema_version))
|
||||
schema = ifcopenshell.util.schema.get_schema_name_from_version(schema_version)
|
||||
else:
|
||||
schema = {"IFC4X3": "IFC4X3_ADD2"}.get(schema, schema)
|
||||
schema = ifcopenshell.util.schema.get_schema_identifier(schema)
|
||||
if f is not None:
|
||||
self.wrapped_data = f
|
||||
if not f.good():
|
||||
@@ -1065,13 +1060,8 @@ class file:
|
||||
|
||||
@property
|
||||
def header(self) -> file_header:
|
||||
# TODO: Workaround for old builds, remove after build stabilizes.
|
||||
# TODO: No need for `wrapped_data.header` to be a method - should use `@property`?
|
||||
header = self.wrapped_data.header
|
||||
if isinstance(header, types.MethodType):
|
||||
return file_header(self, self.wrapped_data.header())
|
||||
else:
|
||||
return self.wrapped_data.header
|
||||
return file_header(self, self.wrapped_data.header())
|
||||
|
||||
@property
|
||||
def storage(self) -> Optional[rocksdb_file_storage]:
|
||||
|
||||
@@ -22,6 +22,8 @@ from __future__ import annotations
|
||||
from collections.abc import Generator, Iterable
|
||||
from typing import TYPE_CHECKING, Any, Literal, Optional, TypeVar, Union, cast, overload
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
from .. import ifcopenshell_wrapper, open
|
||||
from ..entity_instance import entity_instance
|
||||
from ..file import file
|
||||
@@ -302,8 +304,7 @@ class iterator(ifcopenshell_wrapper.Iterator):
|
||||
logger=None,
|
||||
):
|
||||
self.settings = settings
|
||||
if logger is None and (logger_type := getattr(ifcopenshell_wrapper, "logger", None)):
|
||||
logger = logger_type.Root()
|
||||
logger = ifcopenshell.logger_or_root(logger)
|
||||
if isinstance(file_or_filename, file):
|
||||
self.file = file
|
||||
file_or_filename = file_or_filename.wrapped_data
|
||||
@@ -344,10 +345,10 @@ class iterator(ifcopenshell_wrapper.Iterator):
|
||||
include is not None,
|
||||
num_threads,
|
||||
)
|
||||
self.this = initializer(*args, *((logger,) if logger is not None else ()))
|
||||
self.this = initializer(*args, *ifcopenshell.optional_logger_args(logger))
|
||||
else:
|
||||
args = (geometry_library, self.settings, file_or_filename, num_threads)
|
||||
self.this = ifcopenshell_wrapper.construct_iterator(*args, *((logger,) if logger is not None else ()))
|
||||
self.this = ifcopenshell_wrapper.construct_iterator(*args, *ifcopenshell.optional_logger_args(logger))
|
||||
|
||||
if has_occ:
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Any, Literal, Union
|
||||
from typing import Any, Literal, Sequence, Union
|
||||
|
||||
from typing_extensions import Self
|
||||
|
||||
@@ -105,10 +105,12 @@ class IfcSpfHeader:
|
||||
"""
|
||||
|
||||
def __init__(self, *args): ...
|
||||
def assign(self, other): ...
|
||||
def file(self, *args): ...
|
||||
def file_description_py(self): ...
|
||||
def file_name_py(self): ...
|
||||
def file_schema_py(self): ...
|
||||
def logger(self) -> logger: ...
|
||||
def read(self): ...
|
||||
def tryRead(self): ...
|
||||
def write(self, out): ...
|
||||
@@ -138,7 +140,7 @@ class BRepElement(Element):
|
||||
def volume(self): ...
|
||||
|
||||
class ColladaSerializer(WriteOnlyGeometrySerializer):
|
||||
def __init__(self, dae_filename, geometry_settings, settings): ...
|
||||
def __init__(self, dae_filename, geometry_settings, settings, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def object_id(self, o): ...
|
||||
@@ -194,6 +196,7 @@ class ConversionResultShape:
|
||||
def subtract(self, arg2): ...
|
||||
def surface_area_along_direction(self, tol, arg3, along_x, along_y, along_z): ...
|
||||
def surface_genus(self): ...
|
||||
def type(self) -> str: ...
|
||||
def vertices(self): ...
|
||||
def volume(self): ...
|
||||
def wrap_in_compound(self): ...
|
||||
@@ -284,7 +287,7 @@ class GeometrySerializer:
|
||||
def write(self, *args): ...
|
||||
|
||||
class GltfSerializer(WriteOnlyGeometrySerializer):
|
||||
def __init__(self, filename, geometry_settings, settings): ...
|
||||
def __init__(self, filename, geometry_settings, settings, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def ready(self): ...
|
||||
@@ -294,7 +297,7 @@ class GltfSerializer(WriteOnlyGeometrySerializer):
|
||||
def writeHeader(self): ...
|
||||
|
||||
class HdfSerializer(GeometrySerializer):
|
||||
def __init__(self, hdf_filename, geometry_settings, settings, read_only=False): ...
|
||||
def __init__(self, hdf_filename, geometry_settings, settings, read_only=False, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def read(self, *args): ...
|
||||
@@ -370,7 +373,7 @@ class Iterator:
|
||||
...
|
||||
|
||||
def process_concurrently(self): ...
|
||||
def process_finished_rep(self, rep): ...
|
||||
def process_finished_rep(self, rep, kernel=None): ...
|
||||
def progress(self) -> int:
|
||||
"""Return current progress (0-100).
|
||||
|
||||
@@ -390,25 +393,41 @@ class JsonSerializer:
|
||||
def setFile(self, arg2): ...
|
||||
def writeHeader(self): ...
|
||||
|
||||
# TODO: MakeVolume is ignored in SWIG, remove from stub once build is bumped.
|
||||
class MakeVolume:
|
||||
defaultvalue: Any
|
||||
description: Any
|
||||
name: Any
|
||||
|
||||
class OpaqueCoordinate_3:
|
||||
def __init__(self, *args): ...
|
||||
def dot(self, other): ...
|
||||
def get(self, i): ...
|
||||
def get_double(self, i): ...
|
||||
def norm(self): ...
|
||||
def normalized(self): ...
|
||||
def normalized_by_max_abs(self): ...
|
||||
def scale(self, scalar): ...
|
||||
def set(self, i, n): ...
|
||||
def size(self): ...
|
||||
def to_double(self): ...
|
||||
|
||||
class OpaqueCoordinate_4:
|
||||
def __init__(self, *args): ...
|
||||
def dot(self, other): ...
|
||||
def get(self, i): ...
|
||||
def get_double(self, i): ...
|
||||
def norm(self): ...
|
||||
def normalized(self): ...
|
||||
def normalized_by_max_abs(self): ...
|
||||
def scale(self, scalar): ...
|
||||
def set(self, i, n): ...
|
||||
def size(self): ...
|
||||
def to_double(self): ...
|
||||
|
||||
class OpaqueNumber:
|
||||
def __init__(self, *args, **kwargs): ...
|
||||
def clone(self): ...
|
||||
def abs(self): ...
|
||||
def add(self, other): ...
|
||||
def divide(self, other): ...
|
||||
def empty(self): ...
|
||||
def equals(self, other): ...
|
||||
def less_than(self, other): ...
|
||||
def multiply(self, other): ...
|
||||
def negated(self): ...
|
||||
def same_type(self, *args): ...
|
||||
def subtract(self, other): ...
|
||||
def to_double(self): ...
|
||||
def to_string(self): ...
|
||||
|
||||
@@ -466,7 +485,7 @@ class Settings:
|
||||
def setting_names(self): ...
|
||||
|
||||
class SvgSerializer(WriteOnlyGeometrySerializer):
|
||||
def __init__(self, out_filename, geometry_settings, settings): ...
|
||||
def __init__(self, out_filename, geometry_settings, settings, logger=None): ...
|
||||
SH_NONE: Any
|
||||
SH_FULL: Any
|
||||
SH_LEFT: Any
|
||||
@@ -609,7 +628,7 @@ class TriangulationElement(Element):
|
||||
def geometry_pointer(self): ...
|
||||
|
||||
class TtlWktSerializer(WriteOnlyGeometrySerializer):
|
||||
def __init__(self, filename, geometry_settings, settings): ...
|
||||
def __init__(self, filename, geometry_settings, settings, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def ready(self): ...
|
||||
@@ -620,7 +639,7 @@ class TtlWktSerializer(WriteOnlyGeometrySerializer):
|
||||
def writeHeader(self): ...
|
||||
|
||||
class WaveFrontOBJSerializer(WriteOnlyGeometrySerializer):
|
||||
def __init__(self, obj_filename, mtl_filename, geometry_settings, settings): ...
|
||||
def __init__(self, obj_filename, mtl_filename, geometry_settings, settings, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def isTesselated(self): ...
|
||||
def ready(self): ...
|
||||
@@ -635,7 +654,7 @@ class WriteOnlyGeometrySerializer(GeometrySerializer):
|
||||
def read(self, *args): ...
|
||||
|
||||
class XmlSerializer:
|
||||
def __init__(self, file, xml_filename): ...
|
||||
def __init__(self, file, xml_filename, logger=None): ...
|
||||
def finalize(self): ...
|
||||
def ready(self): ...
|
||||
def setFile(self, arg2): ...
|
||||
@@ -643,14 +662,6 @@ class XmlSerializer:
|
||||
|
||||
class _SwigNonDynamicMeta(type): ...
|
||||
|
||||
class abstract_arrangement:
|
||||
def __init__(self, *args, **kwargs): ...
|
||||
def get_face_pairs(self): ...
|
||||
def merge(self, edge_indices): ...
|
||||
def num_edges(self): ...
|
||||
def num_faces(self): ...
|
||||
def write(self, polygons, progress): ...
|
||||
|
||||
class aggregation_type(parameter_type):
|
||||
def __init__(self, type_of_aggregation, bound1, bound2, type_of_element): ...
|
||||
array_type: Any
|
||||
@@ -664,6 +675,15 @@ class aggregation_type(parameter_type):
|
||||
def type_of_aggregation_string(self): ...
|
||||
def type_of_element(self) -> parameter_type: ...
|
||||
|
||||
class arrange_polygon_settings:
|
||||
debug_output: bool
|
||||
line_cleaning_algo: int
|
||||
outer_perimiter_algo: int
|
||||
perform_cleanup: bool
|
||||
polygon_offset_distance: float
|
||||
subdivision_factor: float
|
||||
topology_reconstruction_algo: int
|
||||
|
||||
class attribute:
|
||||
def __init__(self, name, type_of_attribute, optional): ...
|
||||
def name(self) -> str: ...
|
||||
@@ -854,8 +874,22 @@ class ellipse(curve):
|
||||
|
||||
class entity(declaration):
|
||||
def __init__(self, name, is_abstract, index_in_schema, supertype): ...
|
||||
def all_attributes(self) -> tuple[attribute, ...]: ...
|
||||
def all_inverse_attributes(self) -> tuple[inverse_attribute, ...]: ...
|
||||
def all_attributes(self) -> tuple[attribute, ...]:
|
||||
"""Get a tuple of attributes, including those inherited from supertypes."""
|
||||
...
|
||||
|
||||
def attributes(self) -> tuple[attribute, ...]:
|
||||
"""Get a tuple of direct attributes."""
|
||||
...
|
||||
|
||||
def all_inverse_attributes(self) -> tuple[inverse_attribute, ...]:
|
||||
"""Get a tuple of inverse attributes, including those inherited from supertypes."""
|
||||
...
|
||||
|
||||
def inverse_attributes(self) -> tuple[inverse_attribute, ...]:
|
||||
"""Get a tuple of direct inverse attributes."""
|
||||
...
|
||||
|
||||
def argument_types(self) -> tuple[str, ...]:
|
||||
"""Get a tuple of types for each attribute in ``all_attributes()``."""
|
||||
...
|
||||
@@ -869,7 +903,6 @@ class entity(declaration):
|
||||
"""
|
||||
...
|
||||
|
||||
def attributes(self) -> tuple[attribute, ...]: ...
|
||||
def derived(self) -> tuple[bool, ...]:
|
||||
"""Return a tuple of booleans indicating whether each direct attribute is derived."""
|
||||
...
|
||||
@@ -1058,6 +1091,7 @@ class file:
|
||||
instantiate_typed_instances: bool
|
||||
def key_value_store_iter(self, prefix): ...
|
||||
def key_value_store_query(self, key): ...
|
||||
def logger(self) -> logger: ...
|
||||
def process_deletion_inverse(self, inst): ...
|
||||
def recalculate_id_counter(self): ...
|
||||
def remove(self, entity: entity_instance) -> None: ...
|
||||
@@ -1201,6 +1235,51 @@ class line_segment:
|
||||
def size(self): ...
|
||||
def swap(self, v): ...
|
||||
|
||||
class log_message:
|
||||
code: Any
|
||||
instance: Any
|
||||
message: Any
|
||||
product: Any
|
||||
severity: Any
|
||||
timestamp: Any
|
||||
|
||||
def __init__(self, severity, code_prefix, code_number, timestamp, message, inst=None, current_product=None): ...
|
||||
@property
|
||||
def severity_string(self): ...
|
||||
def to_dict(self): ...
|
||||
def to_tuple(self): ...
|
||||
|
||||
class logger:
|
||||
FMT_PLAIN: Literal[0]
|
||||
FMT_JSON: Literal[1]
|
||||
FMT_INMEMORY: Literal[2]
|
||||
|
||||
LOG_PERF: Literal[0]
|
||||
LOG_DEBUG: Literal[1]
|
||||
LOG_NOTICE: Literal[2]
|
||||
LOG_WARNING: Literal[3]
|
||||
LOG_ERROR: Literal[4]
|
||||
|
||||
@staticmethod
|
||||
def Root() -> logger: ...
|
||||
def Append(self, logger): ...
|
||||
def ClearLog(self): ...
|
||||
def Error(self, *args): ...
|
||||
def GetLog(self): ...
|
||||
def MaxSeverity(self): ...
|
||||
def Message(self, *args): ...
|
||||
def Notice(self, *args): ...
|
||||
def OutputFormat(self, *args): ...
|
||||
def PrintPerformanceStats(self): ...
|
||||
def PrintPerformanceStatsOnElement(self, *args): ...
|
||||
def ProgressBar(self, progress): ...
|
||||
def SetOutput(self, *args): ...
|
||||
def SetProduct(self, product): ...
|
||||
def Status(self, message, new_line=True): ...
|
||||
def Verbosity(self, *args): ...
|
||||
def Warning(self, *args): ...
|
||||
def log_messages(self) -> tuple[log_message, ...]: ...
|
||||
|
||||
class loft:
|
||||
axis: Any
|
||||
def calc_hash(self): ...
|
||||
@@ -1695,17 +1774,19 @@ class type_declaration(declaration):
|
||||
|
||||
class uninitialized_tag: ...
|
||||
|
||||
def arrange_polygons(settings, polygons): ...
|
||||
def arrange_polygons(
|
||||
settings: arrange_polygon_settings, polygons: Sequence[polygon_2], logger: logger | None = None
|
||||
) -> tuple[polygon_2, ...]: ...
|
||||
def clear_schemas(): ...
|
||||
def construct_iterator(geometry_library, settings, file, num_threads, logger=...): ...
|
||||
def construct_iterator(geometry_library, settings, file, num_threads, logger=None): ...
|
||||
def construct_iterator_with_include_exclude(
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=...
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=None
|
||||
): ...
|
||||
def construct_iterator_with_include_exclude_globalid(
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=...
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=None
|
||||
): ...
|
||||
def construct_iterator_with_include_exclude_id(
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=...
|
||||
geometry_library, settings, file, elems, include, num_threads, logger=None
|
||||
): ...
|
||||
def convert_loop_to_function_item(loop): ...
|
||||
def create_box(*args): ...
|
||||
@@ -1721,10 +1802,11 @@ def kind_to_string(k): ...
|
||||
def less(arg1, arg2): ...
|
||||
def line_segments_to_polygons(s, eps, segments): ...
|
||||
def map_shape(settings, instance): ...
|
||||
def logger_or_root(logger) -> logger: ...
|
||||
def nary_union(sequence): ...
|
||||
def new_IfcBaseClass(schema_identifier: str, name: str) -> entity_instance: ...
|
||||
def open(fn: str, readonly: bool = False, logger=...) -> file: ...
|
||||
def parse_ifcxml(filename, logger=...): ...
|
||||
def open(fn: str, readonly: bool = False, logger=None) -> file: ...
|
||||
def parse_ifcxml(filename, logger=None): ...
|
||||
def polygons_to_svg(*args): ...
|
||||
def read(data): ...
|
||||
def register_schema(arg1): ...
|
||||
|
||||
@@ -50,6 +50,21 @@ def get_fallback_schema(version: str) -> IFC_SCHEMA:
|
||||
return version
|
||||
|
||||
|
||||
def get_schema_identifier(schema: IFC_SCHEMA) -> str:
|
||||
"""Resolve a general schema name to the specific identifier used internally
|
||||
(as in ``file.schema_identifier``).
|
||||
|
||||
E.g. ``IFC4X3`` -> ``IFC4X3_ADD2``.
|
||||
"""
|
||||
return {"IFC4X3": "IFC4X3_ADD2"}.get(schema, schema)
|
||||
|
||||
|
||||
def get_schema_name_from_version(schema_version: tuple[int, ...]) -> str:
|
||||
"""Build a schema name from a version tuple, e.g. (4, 3, 0, 1) -> "IFC4X3_TC1"."""
|
||||
prefixes = ("IFC", "X", "_ADD", "_TC")
|
||||
return "".join("".join(map(str, t)) if t[1] else "" for t in zip(prefixes, schema_version))
|
||||
|
||||
|
||||
def get_declaration(element: ifcopenshell.entity_instance):
|
||||
"""Get the schema declaration of an actively used entity instance
|
||||
|
||||
@@ -175,8 +190,8 @@ def geometry_classes_introduced_after(target_schema: IFC_SCHEMA, source_schema:
|
||||
B-splines, advanced surfaces, alignment curves on IFC4X3 → 2X3, …) or
|
||||
purge. Defaults match the IFC4 → IFC2X3 case for backwards compatibility
|
||||
with the original caller."""
|
||||
source = ifcopenshell_wrapper.schema_by_name(source_schema)
|
||||
target = ifcopenshell_wrapper.schema_by_name(target_schema)
|
||||
source = ifcopenshell.schema_by_name(source_schema)
|
||||
target = ifcopenshell.schema_by_name(target_schema)
|
||||
target_names = {decl.name() for decl in target.entities()}
|
||||
result: set[str] = set()
|
||||
for decl in source.entities():
|
||||
|
||||
@@ -217,6 +217,7 @@ def test_iterator():
|
||||
|
||||
|
||||
def test_logging():
|
||||
assert ifcopenshell.logger
|
||||
logger = ifcopenshell.logger()
|
||||
logger.OutputFormat(logger.FMT_INMEMORY)
|
||||
settings = ifcopenshell.geom.settings()
|
||||
|
||||
@@ -17,21 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import http.client
|
||||
from collections.abc import Sequence
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from typing_extensions import assert_never
|
||||
|
||||
try:
|
||||
from bs4 import BeautifulSoup
|
||||
except:
|
||||
pass
|
||||
|
||||
# Where it's also reflected:
|
||||
# - .github/workflows/ci-ifcopenshell-python.yml
|
||||
# - .github/workflows/ci-ifcopenshell-python-pypi.yml
|
||||
# - src/ifcopenshell-python/Makefile (PYVERSION check)
|
||||
SUPPORTED_PY_VERSIONS = ("310", "311", "312", "313", "314")
|
||||
SUPPORTED_PLATFORMS = ("win64", "linux64", "macos64", "macosm164")
|
||||
|
||||
@@ -41,24 +31,22 @@ WASM_TEMPLATE = "https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-{BINA
|
||||
|
||||
|
||||
class TestPackageSupportedPlatforms:
|
||||
def test_run(self) -> None:
|
||||
@staticmethod
|
||||
def get_required_urls() -> list[str]:
|
||||
IOS_REPO = Path(__file__).parents[3]
|
||||
makefile = IOS_REPO / "src/ifcopenshell-python/Makefile"
|
||||
text = makefile.read_text()
|
||||
|
||||
# We don't use requests in ifcopenshell, so we use Python builtin stuff.
|
||||
parsed = urlparse("https://builds.ifcopenshell.org")
|
||||
conn = http.client.HTTPSConnection(parsed.netloc)
|
||||
conn.request("GET", parsed.path)
|
||||
response = conn.getresponse()
|
||||
build_html = response.read().decode("utf-8")
|
||||
|
||||
def find_make_var(var_name: str) -> str:
|
||||
line = next(l for l in text.splitlines() if l.startswith(f"{var_name}:="))
|
||||
return line.partition(":=")[2]
|
||||
|
||||
BINARY_VERSION = find_make_var("BINARY_VERSION")
|
||||
BUILD_COMMIT = find_make_var("BUILD_COMMIT")
|
||||
# Build workflows upload artifacts using a 7-char short SHA.
|
||||
assert (
|
||||
l := len(BUILD_COMMIT)
|
||||
) == 7, f"BUILD_COMMIT must be a 7-char short SHA, got {BUILD_COMMIT!r} (length {l})"
|
||||
|
||||
required_urls: list[str] = []
|
||||
|
||||
@@ -97,14 +85,47 @@ class TestPackageSupportedPlatforms:
|
||||
)
|
||||
required_urls.append(url)
|
||||
|
||||
# Verify all required URLs are present in the build HTML.
|
||||
missing_urls: Sequence[str]
|
||||
if "BeautifulSoup" in globals():
|
||||
missing_urls = set(required_urls) - set(a["href"] for a in BeautifulSoup(build_html).find_all("a"))
|
||||
else:
|
||||
missing_urls = []
|
||||
for url in required_urls:
|
||||
if url not in build_html:
|
||||
missing_urls.append(url)
|
||||
return required_urls
|
||||
|
||||
@staticmethod
|
||||
def get_missing_urls_fast(urls: list[str]) -> list[str]:
|
||||
"""Check `urls` against the build listing page.
|
||||
|
||||
Fast, but the listing page can lag behind what's actually on S3, so this may report URLs as
|
||||
missing that do exist.
|
||||
"""
|
||||
# We don't use requests in ifcopenshell, so we use Python builtin stuff.
|
||||
parsed = urlparse("https://builds.ifcopenshell.org")
|
||||
conn = http.client.HTTPSConnection(parsed.netloc)
|
||||
conn.request("GET", parsed.path)
|
||||
response = conn.getresponse()
|
||||
build_html = response.read().decode("utf-8")
|
||||
conn.close()
|
||||
|
||||
return [url for url in urls if url not in build_html]
|
||||
|
||||
@staticmethod
|
||||
def get_missing_urls_slow(urls: list[str]) -> list[str]:
|
||||
"""Check `urls` directly with a HEAD request each.
|
||||
|
||||
Slow, but more reliable.
|
||||
"""
|
||||
missing_urls: list[str] = []
|
||||
for url in urls:
|
||||
parsed = urlparse(url)
|
||||
conn = http.client.HTTPSConnection(parsed.netloc)
|
||||
conn.request("HEAD", parsed.path)
|
||||
response = conn.getresponse()
|
||||
response.read()
|
||||
conn.close()
|
||||
if response.status != 200:
|
||||
missing_urls.append(url)
|
||||
|
||||
return missing_urls
|
||||
|
||||
def test_run(self) -> None:
|
||||
required_urls = self.get_required_urls()
|
||||
maybe_missing_urls = self.get_missing_urls_fast(required_urls)
|
||||
missing_urls = self.get_missing_urls_slow(maybe_missing_urls)
|
||||
|
||||
assert not missing_urls
|
||||
|
||||
@@ -447,7 +447,7 @@ public:
|
||||
};
|
||||
|
||||
#ifdef WITH_IFCXML
|
||||
IFC_PARSE_API IfcFile* parse_ifcxml(const std::string& filename, Logger& logger = Logger::Root());
|
||||
IFC_PARSE_API IfcFile* parse_ifcxml(const std::string& filename, Logger* logger = nullptr);
|
||||
#endif
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -142,6 +142,13 @@ class IFC_PARSE_API Logger {
|
||||
const std::vector<log_message>& log_messages() const { return log_messages_; }
|
||||
};
|
||||
|
||||
// SWIG couldn't represent `Logger::Root()` default value using Python,
|
||||
// so when translating signature it represents it just as `fn(*args)`, losing information about args.
|
||||
// Using `Logger * = nullptr` instead of `&Logger = Logger::Root` helps,
|
||||
// since `nullptr` is convertable Python's `None`.
|
||||
// `logger_or_root` is just covering the boilerplate for this pattern.
|
||||
inline Logger& logger_or_root(Logger* logger) { return logger ? *logger : Logger::Root(); }
|
||||
|
||||
#define PERF(x) \
|
||||
\
|
||||
Logger::Root().Message(Logger::LOG_PERF, "SYS", 1, x); \
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <charconv>
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#include <boost/filesystem/path.hpp>
|
||||
@@ -733,6 +732,41 @@ void IfcParse::impl::rocks_db_file_storage::remove_type_ref(IfcUtil::IfcBaseClas
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Shortest decimal representation of 'd' that round-trips back to the
|
||||
// exact same double (like std::to_chars, or Python's repr).
|
||||
// Using actual `std::to_chars` requires macOS 13.3+, so we implement this manually,
|
||||
// until we drop support for older targets.
|
||||
//
|
||||
// Mirrors libstdc++'s notation-choice bounds (floating_to_chars.cc,
|
||||
// __floating_to_chars_shortest) to pick whichever of fixed/scientific is
|
||||
// shorter for a given digit count and exponent.
|
||||
static inline void format_double_shortest(char (&buf)[64], double d) {
|
||||
char sci[64];
|
||||
int mantissa_length = 17;
|
||||
for (int prec = 1; prec <= 17; ++prec) {
|
||||
snprintf(sci, sizeof(sci), "%.*e", prec - 1, d);
|
||||
if (strtod(sci, nullptr) == d) {
|
||||
mantissa_length = prec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char* exp_str = strchr(sci, 'e');
|
||||
const int scientific_exponent = exp_str ? atoi(exp_str + 1) : 0;
|
||||
const int fd_exponent = scientific_exponent - (mantissa_length - 1);
|
||||
int lower_bound = -(mantissa_length + 3);
|
||||
int upper_bound = 5;
|
||||
if (mantissa_length == 1) {
|
||||
++lower_bound;
|
||||
--upper_bound;
|
||||
}
|
||||
if (fd_exponent >= lower_bound && fd_exponent <= upper_bound) {
|
||||
const int fixed_precision = fd_exponent < 0 ? -fd_exponent : 0;
|
||||
snprintf(buf, 64, "%.*f", fixed_precision, d);
|
||||
} else {
|
||||
snprintf(buf, 64, "%.*e", mantissa_length - 1, d);
|
||||
}
|
||||
}
|
||||
|
||||
class StringBuilderVisitor : public boost::static_visitor<void> {
|
||||
private:
|
||||
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
|
||||
@@ -759,11 +793,9 @@ namespace {
|
||||
// values with noise digits (0.0174532925199433 -> 0.017453292519943299),
|
||||
// which rewrote every REAL and produced huge diffs when a file was
|
||||
// re-saved. See #7696.
|
||||
// std::to_chars is locale-independent, so no ostringstream/imbue is
|
||||
// needed here.
|
||||
char buf[64];
|
||||
const auto res = std::to_chars(buf, buf + sizeof(buf), d);
|
||||
const std::string str(buf, res.ptr);
|
||||
format_double_shortest(buf, d);
|
||||
const std::string str(buf);
|
||||
std::string::size_type e = str.find('e');
|
||||
if (e == std::string::npos) {
|
||||
e = str.find('E');
|
||||
|
||||
@@ -35,7 +35,13 @@ namespace {
|
||||
parse_context pc;
|
||||
storage->tokens->Next();
|
||||
storage->load(-1, nullptr, pc, -1);
|
||||
return pc.construct(boost::none, *storage->references_to_resolve, decl, decl->as_entity()->attribute_count(), -1, logger);
|
||||
// references_to_resolve is unset while reading the header (header
|
||||
// entities such as FILE_DESCRIPTION never reference other
|
||||
// instances), so fall back to a throwaway list instead of
|
||||
// dereferencing a null pointer.
|
||||
unresolved_references no_references;
|
||||
unresolved_references& references = storage->references_to_resolve ? *storage->references_to_resolve : no_references;
|
||||
return pc.construct(boost::none, references, decl, decl->as_entity()->attribute_count(), -1, logger);
|
||||
} else {
|
||||
// std::unreachable();
|
||||
return IfcEntityInstanceData(in_memory_attribute_storage(10));
|
||||
|
||||
@@ -695,10 +695,10 @@ end:
|
||||
return;
|
||||
}
|
||||
|
||||
IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filename, Logger& logger) {
|
||||
IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filename, Logger* logger) {
|
||||
throw std::runtime_error("IFC-XML import temporarily disabled");
|
||||
|
||||
ifcxml_parse_state state(logger);
|
||||
ifcxml_parse_state state(logger_or_root(logger));
|
||||
|
||||
xmlSAXHandler handler;
|
||||
memset(&handler, 0, sizeof(xmlSAXHandler));
|
||||
|
||||
@@ -630,29 +630,33 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||
// I couldn't get the vector<string> typemap to be applied when %extending Iterator constructor.
|
||||
// anyway it does not matter as SWIG generates C code without actual constructors
|
||||
%inline %{
|
||||
IfcGeom::Iterator* construct_iterator(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, int num_threads, Logger& logger = Logger::Root()) {
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, num_threads, logger);
|
||||
IfcGeom::Iterator* construct_iterator(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, int num_threads, Logger* logger = nullptr) {
|
||||
Logger& logger_ = logger_or_root(logger);
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger_), settings, file, num_threads, logger_);
|
||||
}
|
||||
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger* logger = nullptr) {
|
||||
Logger& logger_ = logger_or_root(logger);
|
||||
std::set<std::string> elems_set(elems.begin(), elems.end());
|
||||
IfcGeom::entity_filter ef{ include, false, elems_set };
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {ef}, num_threads, logger);
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger_), settings, file, {ef}, num_threads, logger_);
|
||||
}
|
||||
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads, Logger* logger = nullptr) {
|
||||
Logger& logger_ = logger_or_root(logger);
|
||||
std::set<std::string> elems_set(elems.begin(), elems.end());
|
||||
IfcGeom::attribute_filter af;
|
||||
af.attribute_name = "GlobalId";
|
||||
af.populate(elems_set);
|
||||
af.include = include;
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger_), settings, file, {af}, num_threads, logger_);
|
||||
}
|
||||
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads, Logger& logger = Logger::Root()) {
|
||||
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads, Logger* logger = nullptr) {
|
||||
Logger& logger_ = logger_or_root(logger);
|
||||
std::set<int> elems_set(elems.begin(), elems.end());
|
||||
IfcGeom::instance_id_filter af(include, false, elems_set);
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger), settings, file, {af}, num_threads, logger);
|
||||
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings, logger_), settings, file, {af}, num_threads, logger_);
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -1162,6 +1166,7 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
|
||||
%ignore svgfill::svg_to_polygons;
|
||||
%ignore svgfill::arrange_polygons;
|
||||
%ignore svgfill::abstract_arrangement;
|
||||
%ignore svgfill::context::delete_same_facet_edge_pairs;
|
||||
|
||||
%template(svg_line_segments) std::vector<std::array<svgfill::point_2, 2>>;
|
||||
%template(svg_groups_of_line_segments) std::vector<std::vector<std::array<svgfill::point_2, 2>>>;
|
||||
@@ -1295,9 +1300,9 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<svgfill::polygon_2> arrange_polygons(svgfill::arrange_polygon_settings settings, const std::vector<svgfill::polygon_2>& polygons, Logger& logger = Logger::Root()) {
|
||||
std::vector<svgfill::polygon_2> arrange_polygons(svgfill::arrange_polygon_settings settings, const std::vector<svgfill::polygon_2>& polygons, Logger* logger = nullptr) {
|
||||
std::vector<svgfill::polygon_2> r;
|
||||
if (svgfill::arrange_polygons(settings, polygons, r, logger)) {
|
||||
if (svgfill::arrange_polygons(settings, polygons, r, logger_or_root(logger))) {
|
||||
return r;
|
||||
} else {
|
||||
throw std::runtime_error("Failed to arrange polygons");
|
||||
|
||||
@@ -752,10 +752,10 @@ private:
|
||||
%newobject stream_from_string;
|
||||
|
||||
%inline %{
|
||||
IfcParse::IfcFile* open(const std::string& fn, bool readonly=false, Logger& logger=Logger::Root()) {
|
||||
IfcParse::IfcFile* open(const std::string& fn, bool readonly=false, Logger* logger=nullptr) {
|
||||
IfcParse::IfcFile* f;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
f = new IfcParse::IfcFile(fn, IfcParse::FT_AUTODETECT, readonly, logger);
|
||||
f = new IfcParse::IfcFile(fn, IfcParse::FT_AUTODETECT, readonly, logger_or_root(logger));
|
||||
Py_END_ALLOW_THREADS;
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -219,8 +219,8 @@ private:
|
||||
std::string unit_name;
|
||||
float unit_magnitude;
|
||||
public:
|
||||
ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
|
||||
ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger = nullptr)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, exporter("IfcOpenShell", dae_filename, this, settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get() >= 15)
|
||||
{
|
||||
exporter.serializer = this;
|
||||
|
||||
@@ -53,8 +53,8 @@ static const uint32_t PRIM_TRIANGLE_FAN = 6;
|
||||
static const uint32_t ELEMENT_ARRAY_BUFFER = 34963;
|
||||
static const uint32_t ARRAY_BUFFER = 34962;
|
||||
|
||||
GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
|
||||
GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, filename_(filename)
|
||||
, tmp_filename1_(filename + ".indices.tmp")
|
||||
, tmp_filename2_(filename + ".vertices.tmp")
|
||||
|
||||
@@ -43,7 +43,7 @@ private:
|
||||
|
||||
int writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style);
|
||||
public:
|
||||
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root());
|
||||
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger = nullptr);
|
||||
virtual ~GltfSerializer();
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
|
||||
@@ -55,8 +55,8 @@ herr_t print_stack(hid_t /*estack*/, void*) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HdfSerializer::HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only, Logger& logger)
|
||||
: GeometrySerializer(geometry_settings, settings, logger)
|
||||
HdfSerializer::HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only, Logger* logger)
|
||||
: GeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, hdf_filename(hdf_filename)
|
||||
, settings_(settings)
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
void write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style::ptr& s);
|
||||
|
||||
public:
|
||||
HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only=false, Logger& logger = Logger::Root());
|
||||
HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only=false, Logger* logger = nullptr);
|
||||
virtual ~HdfSerializer() {}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
|
||||
@@ -596,8 +596,8 @@ protected:
|
||||
subtract_before_project subtraction_settings_;
|
||||
|
||||
public:
|
||||
SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
|
||||
SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger = nullptr)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, svg_file(out_filename)
|
||||
, xmin(+std::numeric_limits<double>::infinity())
|
||||
, ymin(+std::numeric_limits<double>::infinity())
|
||||
|
||||
@@ -233,8 +233,8 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
|
||||
TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, filename_(filename)
|
||||
{
|
||||
const auto& tri_setting = geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().get();
|
||||
|
||||
@@ -32,7 +32,7 @@ class SERIALIZERS_API TtlWktSerializer : public WriteOnlyGeometrySerializer {
|
||||
private:
|
||||
stream_or_filename filename_;
|
||||
public:
|
||||
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root());
|
||||
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger = nullptr);
|
||||
virtual ~TtlWktSerializer() {}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
|
||||
WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger)
|
||||
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger_or_root(logger))
|
||||
, obj_stream(obj_filename)
|
||||
, mtl_stream(mtl_filename)
|
||||
, vcount_total(1)
|
||||
|
||||
@@ -35,7 +35,7 @@ private:
|
||||
size_t vcount_total, ncount_total;
|
||||
std::set<std::string> materials;
|
||||
public:
|
||||
WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root());
|
||||
WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger* logger = nullptr);
|
||||
virtual ~WaveFrontOBJSerializer() {}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
|
||||
@@ -31,8 +31,8 @@ XmlSerializer* XmlSerializerFactory::Factory::construct(const std::string& schem
|
||||
return it->second(file, xml_filename, logger);
|
||||
}
|
||||
|
||||
XmlSerializer::XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger)
|
||||
: Serializer(logger) {
|
||||
XmlSerializer::XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger* logger)
|
||||
: Serializer(logger_or_root(logger)) {
|
||||
if (file) {
|
||||
implementation_ = XmlSerializerFactory::implementations().construct(file->schema()->name(), file, xml_filename, logger_);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ protected:
|
||||
std::string xml_filename;
|
||||
|
||||
public:
|
||||
XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger = Logger::Root());
|
||||
XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger* logger = nullptr);
|
||||
|
||||
virtual ~XmlSerializer() {}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
|
||||
public:
|
||||
POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger = Logger::Root())
|
||||
: XmlSerializer(0, "", logger)
|
||||
: XmlSerializer(0, "", &logger)
|
||||
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger))
|
||||
{
|
||||
this->file = file;
|
||||
|
||||
Reference in New Issue
Block a user