diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 9d53219d..00000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[bumpversion] -current_version = 0.3.0 -message = Bump version to {new_version} -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version="{current_version}" -replace = version="{new_version}" - -[bumpversion:file:src/compas_ifc/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:CHANGELOG.md] -search = Unreleased -replace = [{new_version}] {now:%Y-%m-%d} diff --git a/.editorconfig b/.editorconfig index 5f6d3a2d..6a650d15 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,4 @@ # EditorConfig is awesome: http://EditorConfig.org - root = true [*] @@ -9,7 +8,7 @@ insert_final_newline = true indent_style = space indent_size = 4 charset = utf-8 -max_line_length = 180 +max_line_length = 179 [*.{bat,cmd,ps1}] end_of_line = crlf @@ -17,13 +16,15 @@ end_of_line = crlf [*.md] trim_trailing_whitespace = false +[*.yml] +indent_size = 2 + +[*.rst] +indent_size = 4 + [Makefile] indent_style = tab indent_size = 4 -[*.yml] -indent_style = space -indent_size = 2 - [LICENSE] insert_final_newline = false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4cea34c6..48d604c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,11 +13,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.9', '3.10', '3.11'] + os: [macos-latest, windows-latest, ubuntu-latest] + python: ['3.10', '3.11'] steps: - - uses: compas-dev/compas-actions.build@v3 + - uses: compas-dev/compas-actions.build@v4 with: python: ${{ matrix.python }} invoke_lint: true diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 29ece06e..6f0ee0e1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,7 +14,7 @@ jobs: docs: runs-on: windows-latest steps: - - uses: compas-dev/compas-actions.docs@v3 + - uses: compas-dev/compas-actions.docs@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} doc_url: https://compas.dev/compas_ifc diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 629e6dbd..2cbcda00 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,11 +10,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.9', '3.10', '3.11'] + os: [macos-latest, windows-latest, ubuntu-latest] + python: ['3.10', '3.11'] steps: - - uses: compas-dev/compas-actions.build@v3 + - uses: compas-dev/compas-actions.build@v4 with: python: ${{ matrix.python }} invoke_lint: true @@ -24,7 +24,7 @@ jobs: needs: build runs-on: windows-latest steps: - - uses: compas-dev/compas-actions.publish@v2 + - uses: compas-dev/compas-actions.publish@v3 with: pypi_token: ${{ secrets.PYPI }} github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index fa15798a..96a7dd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* Added support to export to `IFC2x3`. +* Added support pre-load geometries using `multi-processing`. + ### Changed * Updated workflow to not use `conda` anymore. * Updated `Reader` to re-enable lazy loading. +* Update repo to use `pyproject.toml`. ### Removed diff --git a/conftest.py b/conftest.py index f63ec775..c9020d8c 100644 --- a/conftest.py +++ b/conftest.py @@ -3,6 +3,7 @@ import compas_ifc import math import numpy +from compas.geometry import allclose def pytest_ignore_collect(path): @@ -15,6 +16,9 @@ def pytest_ignore_collect(path): if "ghpython" in str(path): return True + if str(path).endswith("_cli.py"): + return True + @pytest.fixture(autouse=True) def add_compas(doctest_namespace): @@ -34,3 +38,8 @@ def add_math(doctest_namespace): @pytest.fixture(autouse=True) def add_np(doctest_namespace): doctest_namespace["np"] = numpy + + +@pytest.fixture(autouse=True) +def add_allclose(doctest_namespace): + doctest_namespace["allclose"] = allclose diff --git a/pyproject.toml b/pyproject.toml index 91814cd4..c118881d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,26 +1,129 @@ -[tool.black] -line-length = 120 +[build-system] +requires = ["setuptools>=66.0"] +build-backend = "setuptools.build_meta" + +# ============================================================================ +# project info +# ============================================================================ + +[project] +name = "compas_ifc" +description = "High-level IFC interface for COMPAS." +keywords = ["compas", "ifc", "bim", "interoperability"] +authors = [{ name = "Tom Van Mele", email = "van.mele@arch.ethz.ch" }, { name = "Li Chen", email = "li.chen@arch.ethz.ch" }] +license = { file = "LICENSE" } +readme = "README.md" +requires-python = ">=3.9" +dynamic = ['dependencies', 'optional-dependencies', 'version'] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Topic :: Scientific/Engineering", + "Operating System :: Unix", + "Operating System :: POSIX", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] + +[project.urls] +Homepage = "https://github.com/compas-dev/compas_ifc" +Documentation = "https://compas.dev/compas_ifc/" +Repository = "https://github.com/compas-dev/compas_ifc.git" +Changelog = "https://github.com/compas-dev/compas_ifc/blob/main/CHANGELOG.md" +Issues = "https://github.com/compas-dev/compas_ifc/issues" +Forum = "https://forum.compas-framework.org/" + +# ============================================================================ +# setuptools config +# ============================================================================ + +[tool.setuptools] +package-dir = { "" = "src" } +include-package-data = true +zip-safe = false + +[tool.setuptools.dynamic] +version = { attr = "compas_ifc.__version__" } +dependencies = { file = "requirements.txt" } +optional-dependencies = { dev = { file = "requirements-dev.txt" } } + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] + +# ============================================================================ +# replace pytest.ini +# ============================================================================ [tool.pytest.ini_options] minversion = "6.0" -testpaths = ["tests"] -python_files = [ - "test_*.py", - "tests.py" +testpaths = ["tests", "src/compas_ifc"] +python_files = ["test_*.py", "*_test.py", "test.py"] +addopts = ["-ra", "--strict-markers", "--doctest-glob=*.rst", "--tb=short"] +doctest_optionflags = [ + "NORMALIZE_WHITESPACE", + "IGNORE_EXCEPTION_DETAIL", + "ALLOW_UNICODE", + "ALLOW_BYTES", + "NUMBER", +] + +# ============================================================================ +# replace bumpversion.cfg +# ============================================================================ + +[tool.bumpversion] +current_version = "0.3.0" +message = "Bump version to {new_version}" +commit = true +tag = true + +[[tool.bumpversion.files]] +filename = "src/compas_ifc/__init__.py" +search = "{current_version}" +replace = "{new_version}" + +[[tool.bumpversion.files]] +filename = "CHANGELOG.md" +search = "Unreleased" +replace = "[{new_version}] {now:%Y-%m-%d}" + +# ============================================================================ +# replace setup.cfg +# ============================================================================ + +[tool.black] +line-length = 179 + +[tool.ruff] +line-length = 179 +indent-width = 4 +target-version = "py39" + +[tool.ruff.lint] +select = ["E", "F", "I"] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["I001"] +"tests/*" = ["I001"] +"tasks.py" = ["I001"] + +[tool.ruff.lint.isort] +force-single-line = true +known-first-party = [ + "compas_ifc", ] -addopts = "-ra --strict --doctest-modules --doctest-glob=*.rst --tb=short" -doctest_optionflags= "NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL ALLOW_UNICODE ALLOW_BYTES NUMBER" -filterwarnings = "ignore::DeprecationWarning" - -[tool.isort] -line_length = 120 -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true -force_single_line = true -ensure_newline_before_comments = true -known_first_party = "compas" -default_section = "THIRDPARTY" -forced_separate = "test_compas" -skip = ["__init__.py"] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" + +[tool.ruff.lint.pycodestyle] +max-doc-length = 179 + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = "dynamic" diff --git a/requirements-dev.txt b/requirements-dev.txt index e34965ec..a1579931 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,23 +1,9 @@ -flake8 -black attrs >=17.4 -bump2version >=1.0.1 -check-manifest >=0.36 -compas_invocations -doc8 -graphviz +black >=22.12.0 +bump-my-version +compas_invocations2 invoke >=0.14 -ipykernel -ipython >=5.8 -isort -m2r2 -nbsphinx -pydocstyle -pytest <7.1 +ruff sphinx_compas2_theme -matplotlib -sphinx twine wheel -sphinx_book_theme --e . diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e7f4c123..00000000 --- a/setup.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[bdist_wheel] -universal = 1 - -[flake8] -max-line-length = 120 -extend-ignore = - # See https://github.com/PyCQA/pycodestyle/issues/373 - E203, - # Only keep black line length check because flake8 forces it on comments as well - E501, - -[doc8] -max-line-length = 120 -ignore = D001 - -[pydocstyle] -convention = numpy diff --git a/setup.py b/setup.py deleted file mode 100644 index fb7e048d..00000000 --- a/setup.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# flake8: noqa -from __future__ import absolute_import -from __future__ import print_function - -import io -from os import path - -from setuptools import setup -from setuptools.command.develop import develop -from setuptools.command.install import install - - -here = path.abspath(path.dirname(__file__)) - - -def read(*names, **kwargs): - return io.open( - path.join(here, *names), - encoding=kwargs.get("encoding", "utf8") - ).read() - - -long_description = read("README.md") -requirements = read("requirements.txt").split("\n") -optional_requirements = {} - -setup( - name="compas_ifc", - version="0.3.0", - description="Package for working with IFC files.", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/compas-dev/compas_ifc", - author="Li Chen, Tom Van Mele", - author_email="li.chen@arch.ethz.ch, van.mele@arch.ethz.ch", - license="MIT license", - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Topic :: Scientific/Engineering", - "License :: OSI Approved :: MIT License", - "Operating System :: Unix", - "Operating System :: POSIX", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: Implementation :: CPython", - ], - keywords=[], - project_urls={}, - packages=["compas_ifc"], - package_dir={"": "src"}, - package_data={}, - data_files=[], - include_package_data=True, - zip_safe=False, - install_requires=requirements, - python_requires=">=3.8", - extras_require=optional_requirements, - entry_points={ - "console_scripts": [], - }, - ext_modules=[], -) diff --git a/src/compas_ifc/brep/tessellatedbrep.py b/src/compas_ifc/brep/tessellatedbrep.py index 4ff1c42e..8068c0cf 100644 --- a/src/compas_ifc/brep/tessellatedbrep.py +++ b/src/compas_ifc/brep/tessellatedbrep.py @@ -1,6 +1,6 @@ +import numpy as np from compas.geometry import Geometry from compas.geometry import transform_points_numpy -import numpy as np class TessellatedBrep(Geometry): diff --git a/src/compas_ifc/brep/tessellatedbrepobject.py b/src/compas_ifc/brep/tessellatedbrepobject.py index 7ab5b3dd..867c09cc 100644 --- a/src/compas_ifc/brep/tessellatedbrepobject.py +++ b/src/compas_ifc/brep/tessellatedbrepobject.py @@ -1,8 +1,9 @@ +import numpy as np +from compas.colors import Color +from compas.datastructures import Mesh from compas_viewer.scene import ViewerSceneObject + from .tessellatedbrep import TessellatedBrep -from compas.datastructures import Mesh -from compas.colors import Color -import numpy as np class TessellatedBrepObject(ViewerSceneObject): diff --git a/src/compas_ifc/entities/__init__.py b/src/compas_ifc/entities/__init__.py index 16f0a611..9c0d8159 100644 --- a/src/compas_ifc/entities/__init__.py +++ b/src/compas_ifc/entities/__init__.py @@ -49,7 +49,7 @@ .. code-block:: python for association in entity.HasAssociations: - if association.is_a('IfcRelAssociatesClassification'): + if association.is_a("IfcRelAssociatesClassification"): ... Material Associations @@ -66,14 +66,15 @@ .. code-block:: python for association in entity.HasAssociations: - if association.is_a('IfcRelAssociatesMaterial'): + if association.is_a("IfcRelAssociatesMaterial"): ... Object Composition ================== Objects may be composed into parts to indicate levels of detail, such as a building having multiple storeys, a framed wall having studs, or a task having subtasks. -Composition may form a hierarchy of multiple levels, where an object must have single parent, or if a top-level object then declared within the single project or a project library. +Composition may form a hierarchy of multiple levels, where an object must have single parent, +or if a top-level object then declared within the single project or a project library. Element Composition ------------------- diff --git a/src/compas_ifc/entities/buildingelements.py b/src/compas_ifc/entities/buildingelements.py index 30380458..09db03a2 100644 --- a/src/compas_ifc/entities/buildingelements.py +++ b/src/compas_ifc/entities/buildingelements.py @@ -85,9 +85,7 @@ def composite_body_with_opening(self): from compas_ifc.representation import entity_body_with_opening_geometry if not self._composite_body_with_opening: - self._composite_body_with_opening = entity_body_with_opening_geometry( - entity=self, bodies=self.composite_body, voids=self.composite_opening - ) + self._composite_body_with_opening = entity_body_with_opening_geometry(entity=self, bodies=self.composite_body, voids=self.composite_opening) return self._composite_body_with_opening @composite_body_with_opening.setter diff --git a/src/compas_ifc/entities/entity.py b/src/compas_ifc/entities/entity.py index b1dfe5ce..c3a00c9a 100644 --- a/src/compas_ifc/entities/entity.py +++ b/src/compas_ifc/entities/entity.py @@ -2,7 +2,6 @@ from typing import Union # from typing import Optional - import ifcopenshell import ifcopenshell.util.element import ifcopenshell.util.pset diff --git a/src/compas_ifc/entities/objectdefinition.py b/src/compas_ifc/entities/objectdefinition.py index 8414483c..4720cece 100644 --- a/src/compas_ifc/entities/objectdefinition.py +++ b/src/compas_ifc/entities/objectdefinition.py @@ -41,9 +41,7 @@ def is_decomposed_by(self): @property def children(self): - children = [ - entity for entity in self.model.get_entities_by_type("IfcObjectDefinition") if entity.parent == self - ] + children = [entity for entity in self.model.get_entities_by_type("IfcObjectDefinition") if entity.parent == self] for entity in self.model._new_entities: if entity.parent == self and entity not in children: children.append(entity) diff --git a/src/compas_ifc/entities/project.py b/src/compas_ifc/entities/project.py index 7fb0f696..9697edf7 100644 --- a/src/compas_ifc/entities/project.py +++ b/src/compas_ifc/entities/project.py @@ -4,6 +4,7 @@ from compas.geometry import Frame from compas.geometry import Vector + from compas_ifc.entities.objectdefinition import ObjectDefinition from compas_ifc.entities.site import Building from compas_ifc.entities.site import Site diff --git a/src/compas_ifc/model.py b/src/compas_ifc/model.py index 5cd8c230..ab1bfa0b 100644 --- a/src/compas_ifc/model.py +++ b/src/compas_ifc/model.py @@ -1,20 +1,21 @@ from typing import List -from compas_ifc.entities.element import Element -from compas_ifc.entities.product import Product +import ifcopenshell + from compas_ifc.entities.building import Building from compas_ifc.entities.buildingelements import BuildingElement -from compas_ifc.entities.geographicelement import GeographicElement from compas_ifc.entities.buildingelements import BuildingElementProxy from compas_ifc.entities.buildingstorey import BuildingStorey -from compas_ifc.entities.objectdefinition import ObjectDefinition +from compas_ifc.entities.element import Element from compas_ifc.entities.entity import Entity +from compas_ifc.entities.geographicelement import GeographicElement +from compas_ifc.entities.objectdefinition import ObjectDefinition +from compas_ifc.entities.product import Product from compas_ifc.entities.project import Project from compas_ifc.entities.site import Site from .reader import IFCReader from .writer import IFCWriter -import ifcopenshell class Model: @@ -60,9 +61,7 @@ class Model: """ - def __init__( - self, filepath: str = None, entity_types: dict = None, use_occ=False, schema=None, load_geometries=True - ) -> None: + def __init__(self, filepath: str = None, entity_types: dict = None, use_occ=False, schema=None, load_geometries=True) -> None: self.reader = IFCReader(model=self, entity_types=entity_types, use_occ=use_occ) self.writer = IFCWriter(model=self) self._new_entities = set() diff --git a/src/compas_ifc/reader.py b/src/compas_ifc/reader.py index b7a05448..81b34268 100644 --- a/src/compas_ifc/reader.py +++ b/src/compas_ifc/reader.py @@ -1,11 +1,11 @@ +import multiprocessing +import os +import time from typing import List import ifcopenshell -import os -import multiprocessing import numpy as np from compas.geometry import Transformation -import time from compas_ifc.entities.entity import Entity @@ -148,9 +148,7 @@ def load_geometries(self, include=None, exclude=None): if self.use_occ: settings.set(settings.USE_PYTHON_OPENCASCADE, True) - iterator = ifcopenshell.geom.iterator( - settings, self._file, multiprocessing.cpu_count(), include=include, exclude=exclude - ) + iterator = ifcopenshell.geom.iterator(settings, self._file, multiprocessing.cpu_count(), include=include, exclude=exclude) start = time.time() if iterator.initialize(): while True: diff --git a/src/compas_ifc/representation.py b/src/compas_ifc/representation.py index 24433c5b..fa4f4423 100644 --- a/src/compas_ifc/representation.py +++ b/src/compas_ifc/representation.py @@ -41,21 +41,21 @@ from operator import mul from typing import List +from compas.geometry import Box +from compas.geometry import Scale +from compas.geometry import Transformation from compas_occ.brep import OCCBrep from OCC.Core.BRep import BRep_Builder from OCC.Core.TopoDS import TopoDS_Compound -from compas.geometry import Box -from compas.geometry import Scale -from compas.geometry import Transformation -from compas_ifc.entities.entity import Entity from compas_ifc.brep import TessellatedBrep +from compas_ifc.entities.entity import Entity from compas_ifc.resources import IfcAxis2Placement3D_to_frame from compas_ifc.resources import IfcBoundingBox_to_box from compas_ifc.resources import IfcCartesianTransformationOperator3D_to_frame from compas_ifc.resources import IfcIndexedPolyCurve_to_lines -from compas_ifc.resources import IfcLocalPlacement_to_transformation from compas_ifc.resources import IfcLocalPlacement_to_frame +from compas_ifc.resources import IfcLocalPlacement_to_transformation from compas_ifc.resources import IfcShape_to_brep from compas_ifc.resources import IfcShape_to_tessellatedbrep @@ -87,7 +87,6 @@ def entity_transformation(entity: Entity): def _entity_transformation(_entity, scale=1.0): - if _entity.ObjectPlacement: scaled_placement = IfcLocalPlacement_to_transformation(_entity.ObjectPlacement, scale=scale) else: diff --git a/src/compas_ifc/resources/brep.py b/src/compas_ifc/resources/brep.py index c78f0da1..ddd4298c 100644 --- a/src/compas_ifc/resources/brep.py +++ b/src/compas_ifc/resources/brep.py @@ -1,13 +1,12 @@ +from typing import List + import ifcopenshell import numpy as np - -from typing import List from compas.tolerance import TOL -from .primities import point_to_ifc_cartesian_point -from .primities import occ_plane_to_frame from .primities import frame_to_ifc_plane - +from .primities import occ_plane_to_frame +from .primities import point_to_ifc_cartesian_point from .shapes import occ_cylinder_to_ifc_cylindrical_surface @@ -149,9 +148,7 @@ def get_ifc_curve(edge): if not IfcEdgeCurve: raise ValueError("Edge not found") - ifc_oriented_edge = file.create_entity( - "IFCORIENTEDEDGE", EdgeElement=IfcEdgeCurve, Orientation=oriented - ) + ifc_oriented_edge = file.create_entity("IFCORIENTEDEDGE", EdgeElement=IfcEdgeCurve, Orientation=oriented) ifc_oriented_edges.append(ifc_oriented_edge) edge_loop = file.create_entity("IfcEdgeLoop", ifc_oriented_edges) @@ -167,26 +164,18 @@ def get_ifc_curve(edge): occ_plane = face.occ_adaptor.Plane() frame = occ_plane_to_frame(occ_plane) ifc_plane = frame_to_ifc_plane(file, frame) - IfcAdvancedFace = file.create_entity( - "IfcAdvancedFace", face_bounds, ifc_plane, SameSense=same_sense - ) + IfcAdvancedFace = file.create_entity("IfcAdvancedFace", face_bounds, ifc_plane, SameSense=same_sense) elif face.is_cylinder: cylinder = face.occ_adaptor.Cylinder() IfcCylindricalSurface = occ_cylinder_to_ifc_cylindrical_surface(file, cylinder) - IfcAdvancedFace = file.create_entity( - "IfcAdvancedFace", face_bounds, IfcCylindricalSurface, SameSense=same_sense - ) + IfcAdvancedFace = file.create_entity("IfcAdvancedFace", face_bounds, IfcCylindricalSurface, SameSense=same_sense) else: control_points = np.array(face.nurbssurface.points.points, dtype=float) control_points = control_points.swapaxes(0, 1) ifc_control_points = [] - u_knots, u_mults = calculate_knots_and_multiplicities( - list(face.nurbssurface.occ_surface.UKnotSequence()) - ) - v_knots, v_mults = calculate_knots_and_multiplicities( - list(face.nurbssurface.occ_surface.VKnotSequence()) - ) + u_knots, u_mults = calculate_knots_and_multiplicities(list(face.nurbssurface.occ_surface.UKnotSequence())) + v_knots, v_mults = calculate_knots_and_multiplicities(list(face.nurbssurface.occ_surface.VKnotSequence())) for row in control_points: ifc_row = [] @@ -237,9 +226,7 @@ def get_ifc_curve(edge): WeightsData=ifc_weights, ) - IfcAdvancedFace = file.create_entity( - "IfcAdvancedFace", face_bounds, IfcBSplineSurfaceWithKnots, SameSense=same_sense - ) + IfcAdvancedFace = file.create_entity("IfcAdvancedFace", face_bounds, IfcBSplineSurfaceWithKnots, SameSense=same_sense) ifc_faces.append(IfcAdvancedFace) diff --git a/src/compas_ifc/resources/geometricmodel.py b/src/compas_ifc/resources/geometricmodel.py index 7cf3663e..6c9cea34 100644 --- a/src/compas_ifc/resources/geometricmodel.py +++ b/src/compas_ifc/resources/geometricmodel.py @@ -1,16 +1,17 @@ from typing import List +import ifcopenshell + # from compas.geometry import Polyline from compas.geometry import Box from compas.geometry import Line from compas.geometry import Point from compas.geometry import Transformation + from compas_ifc.resources.geometry import IfcAxis2Placement3D_to_frame from compas_ifc.resources.geometry import IfcDirection_to_vector from compas_ifc.resources.geometry import IfcProfileDef_to_curve -import ifcopenshell - def IfcAdvancedBrep_to_brep(advanced_brep): """ diff --git a/src/compas_ifc/resources/mesh.py b/src/compas_ifc/resources/mesh.py index 7d0b39d5..5868e865 100644 --- a/src/compas_ifc/resources/mesh.py +++ b/src/compas_ifc/resources/mesh.py @@ -1,5 +1,4 @@ import ifcopenshell - from compas.datastructures import Mesh diff --git a/src/compas_ifc/resources/primities.py b/src/compas_ifc/resources/primities.py index 111091b2..9df02771 100644 --- a/src/compas_ifc/resources/primities.py +++ b/src/compas_ifc/resources/primities.py @@ -1,7 +1,7 @@ import ifcopenshell - from compas.geometry import Frame from compas.geometry import Point + from .shapes import create_IfcAxis2Placement3D diff --git a/src/compas_ifc/resources/representation.py b/src/compas_ifc/resources/representation.py index 9df411da..f64798d1 100644 --- a/src/compas_ifc/resources/representation.py +++ b/src/compas_ifc/resources/representation.py @@ -1,10 +1,9 @@ -from ifcopenshell.api import run - from compas.datastructures import Mesh from compas.geometry import Box from compas.geometry import Cone from compas.geometry import Cylinder from compas.geometry import Sphere +from ifcopenshell.api import run from .brep import brep_to_ifc_advanced_brep from .mesh import mesh_to_IfcPolygonalFaceSet diff --git a/src/compas_ifc/resources/shapes.py b/src/compas_ifc/resources/shapes.py index a1f53772..36042114 100644 --- a/src/compas_ifc/resources/shapes.py +++ b/src/compas_ifc/resources/shapes.py @@ -1,5 +1,4 @@ import ifcopenshell - from compas.geometry import Box from compas.geometry import Cone from compas.geometry import Cylinder @@ -21,9 +20,7 @@ def create_IfcAxis2Placement3D(file, point=None, dir1=None, dir2=None): return axis2placement -def create_IfcShapeRepresentation( - file: ifcopenshell.file, item: ifcopenshell.entity_instance, context: ifcopenshell.entity_instance -) -> ifcopenshell.entity_instance: +def create_IfcShapeRepresentation(file: ifcopenshell.file, item: ifcopenshell.entity_instance, context: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance: """ Create an IFC Shape Representation from an IFC item and a context. """ diff --git a/src/compas_ifc/writer.py b/src/compas_ifc/writer.py index ba18353f..4c5f86c4 100644 --- a/src/compas_ifc/writer.py +++ b/src/compas_ifc/writer.py @@ -1,17 +1,17 @@ +import time + import ifcopenshell from ifcopenshell.api import run -from .entities.objectdefinition import ObjectDefinition from .entities.element import Element from .entities.entity import Entity +from .entities.objectdefinition import ObjectDefinition from .entities.product import Product from .entities.project import Project from .entities.root import Root from .resources.representation import write_body_representation from .resources.shapes import frame_to_ifc_axis2_placement_3d -import time - class IFCWriter(object): """ @@ -81,9 +81,7 @@ def default_body_context(self): def default_project(self): if not self._default_project: if not self.model.projects: - self._default_project = self.file.create_entity( - "IfcProject", GlobalId=self.create_guid(), Name="Default Project" - ) + self._default_project = self.file.create_entity("IfcProject", GlobalId=self.create_guid(), Name="Default Project") run("unit.assign_unit", self.file) else: self._default_project = self.write_entity(self.model.projects[0]) @@ -93,9 +91,7 @@ def default_project(self): def default_site(self): if not self._default_site: if not self.model.sites: - self._default_site = self.file.create_entity( - "IfcSite", Name="Default Site", GlobalId=self.create_guid() - ) + self._default_site = self.file.create_entity("IfcSite", Name="Default Site", GlobalId=self.create_guid()) self.file.create_entity( "IfcRelAggregates", GlobalId=self.create_guid(), @@ -110,9 +106,7 @@ def default_site(self): def default_building(self): if not self._default_building: if not self.model.buildings: - self._default_building = self.file.create_entity( - "IfcBuilding", GlobalId=self.create_guid(), Name="Default Building" - ) + self._default_building = self.file.create_entity("IfcBuilding", GlobalId=self.create_guid(), Name="Default Building") self.file.create_entity( "IfcRelAggregates", GlobalId=self.create_guid(), @@ -127,9 +121,7 @@ def default_building(self): def default_building_storey(self): if not self._default_building_storey: if not self.model.building_storeys: - self._default_building_storey = self.file.create_entity( - "IfcBuildingStorey", GlobalId=self.create_guid(), Name="Default Storey" - ) + self._default_building_storey = self.file.create_entity("IfcBuildingStorey", GlobalId=self.create_guid(), Name="Default Storey") self.file.create_entity( "IfcRelAggregates", GlobalId=self.create_guid(), @@ -142,15 +134,12 @@ def default_building_storey(self): @property def default_owner_history(self): - if not self._default_owner_history: import compas_ifc person = self.file.create_entity("IfcPerson") organization = self.file.create_entity("IfcOrganization", Name="compas.dev") - person_and_org = self.file.create_entity( - "IfcPersonAndOrganization", ThePerson=person, TheOrganization=organization - ) + person_and_org = self.file.create_entity("IfcPersonAndOrganization", ThePerson=person, TheOrganization=organization) application = self.file.create_entity( "IfcApplication", ApplicationDeveloper=organization, @@ -280,9 +269,7 @@ def create_new_relation(self, entity: ObjectDefinition): RelatedElements=[child], ) else: - self.file.create_entity( - "IfcRelAggregates", GlobalId=self.create_guid(), RelatingObject=parent, RelatedObjects=[child] - ) + self.file.create_entity("IfcRelAggregates", GlobalId=self.create_guid(), RelatingObject=parent, RelatedObjects=[child]) def write_entity(self, entity: Entity) -> None: """Writes the given entity recursively with all its referencing attributes to the ifc file.""" @@ -327,10 +314,8 @@ def write_entity_representation(self, entity: Entity): """Writes the representations of the given entity to the ifc file.""" if isinstance(entity, Product): if entity.body: - if not id(entity.body) in self._representationmap: - representation = write_body_representation( - self.file, entity.body, self._entitymap[entity], self.default_body_context - ) + if id(entity.body) not in self._representationmap: + representation = write_body_representation(self.file, entity.body, self._entitymap[entity], self.default_body_context) self._representationmap[id(entity.body)] = representation else: representation = self._representationmap[id(entity.body)] diff --git a/tasks.py b/tasks.py index d1bbbc51..baafa5b6 100644 --- a/tasks.py +++ b/tasks.py @@ -2,10 +2,10 @@ import os -from compas_invocations import build -from compas_invocations import docs -from compas_invocations import style -from compas_invocations import tests +from compas_invocations2 import build +from compas_invocations2 import docs +from compas_invocations2 import style +from compas_invocations2 import tests from invoke import Collection ns = Collection(