Simplify packaging, add create project smoke test. New license target.

This commit is contained in:
Dion Moult
2021-09-03 14:11:15 +10:00
parent 81b0442abe
commit b71684955d
25 changed files with 400 additions and 205 deletions
+4 -3
View File
@@ -26,7 +26,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
submodules: recursive submodules: recursive
- name: Install dependencies - name: Install C++ dependencies
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --no-install-recommends \ sudo apt-get install --no-install-recommends \
@@ -68,16 +68,17 @@ jobs:
sudo make -j $(nproc) sudo make -j $(nproc)
sudo make install sudo make install
- name: install dependencies - name: Install Python dependencies
run: | run: |
sudo /usr/bin/python -m pip install -U pip sudo /usr/bin/python -m pip install -U pip
sudo /usr/bin/python -m pip install xmlschema numpy lxml sudo /usr/bin/python -m pip install xmlschema numpy lxml
sudo /usr/bin/python -m pip install src/bcf sudo /usr/bin/python -m pip install src/bcf
sudo /usr/bin/python -m pip install pytest
- name: Test - name: Test
run: | run: |
cd test cd test
sudo /usr/bin/python tests.py sudo /usr/bin/python tests.py
cd ../src/ifcopenshell-python cd ../src/ifcopenshell-python
sudo /usr/bin/python -m pip install pytest mv ifcopenshell ifcopenshell-local # Force testing on installed module
make test make test
+8
View File
@@ -32,8 +32,10 @@ Pipfile.lock
# gettext binary translation files # gettext binary translation files
*.mo *.mo
# Vim # Vim
*.swp *.swp
*.swo
# Flask # Flask
instance/* instance/*
@@ -53,3 +55,9 @@ Pipfile.lock
# Database # Database
*.db *.db
# PyTest
htmlcov
.coverage
# Blender
*.blend1
+42
View File
@@ -1,3 +1,21 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
VERSION:=`date '+%y%m%d'` VERSION:=`date '+%y%m%d'`
PYVERSION:=py37 PYVERSION:=py37
@@ -413,6 +431,30 @@ endif
cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./* cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./*
rm -rf dist/blenderbim rm -rf dist/blenderbim
.PHONY: test
test:
make test-core
make test-bim
.PHONY: test-core
test-core:
pytest -p no:pytest-blender test/core
.PHONY: test-bim
test-bim:
pytest test/bim
.PHONY: coverage
coverage:
coverage run --source blenderbim.core -m pytest -p no:pytest-blender test/core
coverage html
xdg-open htmlcov/index.html
.PHONY: license
license:
copyright-header --license GPL3 --copyright-holder "Dion Moult <dion@thinkmoult.com>" --copyright-year "2021" --copyright-software "BlenderBIM Add-on" --copyright-software-description "OpenBIM Blender Add-on" -a ./ -o ./
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf dist rm -rf dist
rm -rf htmlcov
+15 -21
View File
@@ -17,10 +17,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import site
bl_info = { bl_info = {
"name": "BlenderBIM", "name": "BlenderBIM",
"description": "Author, import, and export files in the " "Industry Foundation Classes (.ifc) file format", "description": "Author, import, and export data using the Industry Foundation Classes schema",
"author": "Dion Moult, IfcOpenShell", "author": "IfcOpenShell Contributors",
"blender": (2, 80, 0), "blender": (2, 80, 0),
"version": (0, 0, 999999), "version": (0, 0, 999999),
"location": "File > Export, File > Import, Scene / Object / Material / Mesh Properties", "location": "File > Export, File > Import, Scene / Object / Material / Mesh Properties",
@@ -28,25 +32,15 @@ bl_info = {
"category": "Import-Export", "category": "Import-Export",
} }
import os if sys.modules.get("bpy", None):
import site # Process *.pth in /libs/site/packages to setup globally importable modules
# This is 3 levels deep as required by the static RPATH of ../../ from dependencies taken from Anaconda
site.addsitedir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "libs", "site", "packages"))
import blenderbim.bim
# process *.pth in /libs/site/packages to setup globally importable modules def register():
# 3 levels deep required by occ static ../../ path blenderbim.bim.register()
# TODO: 3 levels deep is no longer required as we no longer bundle OCC
cwd = os.path.dirname(os.path.realpath(__file__))
site.addsitedir(os.path.join(cwd, "libs", "site", "packages"))
def unregister():
# main import blenderbim.bim.unregister()
from .bim import *
# Explicitely expose bim.xx when imported with from blenderbim import *
# Other bim still are importable using explicit from blenderbim.bim import xxx
__all__ = ["export_ifc", "import_ifc"]
if __name__ == "__main__":
register()
+133 -143
View File
@@ -17,157 +17,147 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
# Check if we are running in Blender before loading, to allow for multiprocessing import bpy
import sys import importlib
from . import handler, ui, prop, operator
bpy = sys.modules.get("bpy") modules = {
"project": None,
"search": None,
"bcf": None,
"root": None,
"unit": None,
"model": None,
"georeference": None,
"context": None,
"drawing": None,
"attribute": None,
"type": None,
"spatial": None,
"void": None,
"aggregate": None,
"geometry": None,
"cobie": None,
"resource": None,
"cost": None,
"sequence": None,
"group": None,
"system": None,
"structural": None,
"boundary": None,
"profile": None,
"material": None,
"style": None,
"layer": None,
"owner": None,
"pset": None,
"qto": None,
"classification": None,
"constraint": None,
"document": None,
"pset_template": None,
"clash": None,
"lca": None,
"csv": None,
"bimtester": None,
"diff": None,
"patch": None,
"covetool": None,
"augin": None,
"debug": None,
}
if bpy is not None: for name in modules.keys():
import bpy modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}")
import importlib
from . import handler, ui, prop, operator
modules = { classes = [
"project": None, operator.OpenUri,
"search": None, operator.SelectDataDir,
"bcf": None, operator.SelectSchemaDir,
"root": None, operator.SelectIfcFile,
"unit": None, operator.ExportIFC,
"model": None, operator.ImportIFC,
"georeference": None, operator.OpenUpstream,
"context": None, operator.AddSectionPlane,
"drawing": None, operator.RemoveSectionPlane,
"attribute": None, operator.ReloadIfcFile,
"type": None, operator.AddIfcFile,
"spatial": None, operator.RemoveIfcFile,
"void": None, operator.SetOverrideColour,
"aggregate": None, operator.SetViewportShadowFromSun,
"geometry": None, operator.LinkIfc,
"cobie": None, operator.SnapSpacesTogether,
"resource": None, prop.StrProperty,
"cost": None, prop.Attribute,
"sequence": None, prop.BIMProperties,
"group": None, prop.IfcParameter,
"system": None, prop.PsetQto,
"structural": None, prop.GlobalId,
"boundary": None, prop.BIMObjectProperties,
"profile": None, prop.BIMMaterialProperties,
"material": None, prop.BIMMeshProperties,
"style": None, ui.BIM_PT_section_plane,
"layer": None, ui.BIM_UL_generic,
"owner": None, ui.BIM_UL_topics,
"pset": None, ui.BIM_ADDON_preferences,
"qto": None, ]
"classification": None,
"constraint": None,
"document": None,
"pset_template": None,
"clash": None,
"lca": None,
"csv": None,
"bimtester": None,
"diff": None,
"patch": None,
"covetool": None,
"augin": None,
"debug": None,
}
for name in modules.keys(): for mod in modules.values():
modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}") classes.extend(mod.classes)
classes = [ def menu_func_export(self, context):
operator.OpenUri, self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)")
operator.SelectDataDir,
operator.SelectSchemaDir,
operator.SelectIfcFile,
operator.ExportIFC,
operator.ImportIFC,
operator.OpenUpstream,
operator.AddSectionPlane,
operator.RemoveSectionPlane,
operator.ReloadIfcFile,
operator.AddIfcFile,
operator.RemoveIfcFile,
operator.SetOverrideColour,
operator.SetViewportShadowFromSun,
operator.LinkIfc,
operator.SnapSpacesTogether,
prop.StrProperty,
prop.Attribute,
prop.BIMProperties,
prop.IfcParameter,
prop.PsetQto,
prop.GlobalId,
prop.BIMObjectProperties,
prop.BIMMaterialProperties,
prop.BIMMeshProperties,
ui.BIM_PT_section_plane,
ui.BIM_UL_generic,
ui.BIM_UL_topics,
ui.BIM_ADDON_preferences,
]
for module in modules.values(): def menu_func_import(self, context):
classes.extend(module.classes) self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)")
def menu_func_export(self, context): def on_register(scene):
self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)") handler.setDefaultProperties(scene)
bpy.app.handlers.depsgraph_update_post.remove(on_register)
def menu_func_import(self, context): def register():
self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)") for cls in classes:
bpy.utils.register_class(cls)
bpy.app.handlers.depsgraph_update_post.append(on_register)
bpy.app.handlers.undo_pre.append(handler.undo_pre)
bpy.app.handlers.undo_post.append(handler.undo_post)
bpy.app.handlers.redo_pre.append(handler.redo_pre)
bpy.app.handlers.redo_post.append(handler.redo_post)
bpy.app.handlers.load_post.append(handler.setDefaultProperties)
bpy.app.handlers.load_post.append(handler.loadIfcStore)
bpy.app.handlers.save_pre.append(handler.ensureIfcExported)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.SCENE_PT_unit.append(ui.ifc_units)
def on_register(scene): for mod in modules.values():
handler.setDefaultProperties(scene) mod.register()
bpy.app.handlers.depsgraph_update_post.remove(on_register)
def register(): def unregister():
for cls in classes: for cls in reversed(classes):
bpy.utils.register_class(cls) bpy.utils.unregister_class(cls)
bpy.app.handlers.depsgraph_update_post.append(on_register) bpy.app.handlers.load_post.remove(handler.setDefaultProperties)
bpy.app.handlers.undo_pre.append(handler.undo_pre) bpy.app.handlers.load_post.remove(handler.loadIfcStore)
bpy.app.handlers.undo_post.append(handler.undo_post) bpy.app.handlers.save_pre.remove(handler.ensureIfcExported)
bpy.app.handlers.redo_pre.append(handler.redo_pre) bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
bpy.app.handlers.redo_post.append(handler.redo_post) bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
bpy.app.handlers.load_post.append(handler.setDefaultProperties) del bpy.types.Scene.BIMProperties
bpy.app.handlers.load_post.append(handler.loadIfcStore) del bpy.types.Object.BIMObjectProperties
bpy.app.handlers.save_pre.append(handler.ensureIfcExported) del bpy.types.Material.BIMObjectProperties
bpy.types.TOPBAR_MT_file_export.append(menu_func_export) del bpy.types.Material.BIMMaterialProperties
bpy.types.TOPBAR_MT_file_import.append(menu_func_import) del bpy.types.Mesh.BIMMeshProperties
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties) del bpy.types.Curve.BIMMeshProperties
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) del bpy.types.Camera.BIMMeshProperties
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) del bpy.types.PointLight.BIMMeshProperties
bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty( bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
type=prop.BIMObjectProperties
) # Check if we need this
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.Camera.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.PointLight.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
bpy.types.SCENE_PT_unit.append(ui.ifc_units)
for module in modules.values(): for mod in reversed(list(modules.values())):
module.register() mod.unregister()
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
bpy.app.handlers.load_post.remove(handler.setDefaultProperties)
bpy.app.handlers.load_post.remove(handler.loadIfcStore)
bpy.app.handlers.save_pre.remove(handler.ensureIfcExported)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
del bpy.types.Scene.BIMProperties
del bpy.types.Object.BIMObjectProperties
del bpy.types.Material.BIMObjectProperties
del bpy.types.Collection.BIMObjectProperties # Check if we need this
del bpy.types.Material.BIMMaterialProperties
del bpy.types.Mesh.BIMMeshProperties
del bpy.types.Curve.BIMMeshProperties
del bpy.types.Camera.BIMMeshProperties
del bpy.types.PointLight.BIMMeshProperties
bpy.types.SCENE_PT_unit.remove(ui.ifc_units)
for module in reversed(list(modules.values())):
module.unregister()
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
@@ -21,7 +21,6 @@ import logging
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.representation import ifcopenshell.util.representation
import bpy
import blenderbim.bim.handler import blenderbim.bim.handler
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim import import_ifc from blenderbim.bim import import_ifc
@@ -1,3 +0,0 @@
# expose hppfcl as site-package
hppfcl
@@ -1,3 +0,0 @@
# expose ifcopenshell as site-package
ifcopenshell
@@ -1,3 +0,0 @@
# setup svgwrite
svgwrite
+19
View File
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
+19
View File
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
+28
View File
@@ -0,0 +1,28 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import pytest
from blenderbim.bim.ifc import IfcStore
class NewFile:
@pytest.fixture(autouse=True)
def setup(self):
IfcStore.purge()
bpy.ops.wm.read_homefile(app_template="")
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
@@ -1,4 +1,3 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on # BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com> # Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com>
# #
@@ -19,11 +18,10 @@
import pytest import pytest
from mathutils import Vector from mathutils import Vector
from blenderbim.bim.module.drawing.helper import clip_segment
from blenderbim.bim.helper import clip_segment
BOUNDS = (10, 30, 10, 30) BOUNDS = (10, 30, 10, 30, None, None)
SEGMENTS_INSIDE = ( SEGMENTS_INSIDE = (
(Vector((15, 20)), Vector((25, 20))), (Vector((15, 20)), Vector((25, 20))),
@@ -40,7 +38,7 @@ SEGMENTS_OUTSIDE = (
(Vector((25, 5)), Vector((15, 5))), (Vector((25, 5)), Vector((15, 5))),
(Vector((15, 5)), Vector((5, 15))), (Vector((15, 5)), Vector((5, 15))),
(Vector((5, 15)), Vector((5, 25))), (Vector((5, 15)), Vector((5, 25))),
(Vector((5, 25)), Vector((15, 35))) (Vector((5, 25)), Vector((15, 35))),
) )
SEGMENTS_CLIPPED = ( SEGMENTS_CLIPPED = (
@@ -54,19 +52,20 @@ SEGMENTS_CLIPPED = (
((Vector((35, 20)), Vector((20, 5))), (Vector((30, 15)), Vector((25, 10)))), ((Vector((35, 20)), Vector((20, 5))), (Vector((30, 15)), Vector((25, 10)))),
) )
@pytest.mark.parametrize('segment', SEGMENTS_INSIDE)
@pytest.mark.parametrize("segment", SEGMENTS_INSIDE)
def test_clip_inside(segment): def test_clip_inside(segment):
clipped = clip_segment(BOUNDS, segment) clipped = clip_segment(BOUNDS, segment)
assert clipped == segment assert clipped == segment
@pytest.mark.parametrize('segment', SEGMENTS_OUTSIDE) @pytest.mark.parametrize("segment", SEGMENTS_OUTSIDE)
def test_clip_outside(segment): def test_clip_outside(segment):
clipped = clip_segment(BOUNDS, segment) clipped = clip_segment(BOUNDS, segment)
assert clipped is None assert clipped is None
@pytest.mark.parametrize('segment,expected', SEGMENTS_CLIPPED) @pytest.mark.parametrize("segment,expected", SEGMENTS_CLIPPED)
def test_clip_crossing(segment, expected): def test_clip_crossing(segment, expected):
clipped = clip_segment(BOUNDS, segment) clipped = clip_segment(BOUNDS, segment)
assert clipped == expected assert clipped == expected
@@ -0,0 +1,19 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,29 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import pytest
import test.bim.bootstrap
from blenderbim.bim.ifc import IfcStore
class TestCreateProject(test.bim.bootstrap.NewFile):
def test_creating_a_project(self):
assert IfcStore.get_file() is None
bpy.ops.bim.create_project()
assert IfcStore.get_file()
+1 -1
View File
@@ -1,6 +1,6 @@
.PHONY: test .PHONY: test
test: test:
cd test && pytest pytest -p no:pytest-blender test
.PHONY: coverage .PHONY: coverage
coverage: coverage:
+1 -1
View File
@@ -1092,7 +1092,7 @@ class BcfHandler(logging.StreamHandler):
bcf_handler = BcfHandler( bcf_handler = BcfHandler(
project_name="Default IDS Project", project_name="Default IDS Project",
author="your@email.com", author="your@email.com",
filepath=r".\example.bcfzip", filepath="example.bcf",
) )
logger = logging.getLogger("IDS_Logger") logger = logging.getLogger("IDS_Logger")
logging.basicConfig(level=logging.INFO, format="%(message)s") logging.basicConfig(level=logging.INFO, format="%(message)s")
+3 -3
View File
@@ -1,11 +1,11 @@
import pytest import pytest
import bootstrap import test.bootstrap
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element import ifcopenshell.util.element
class TestTransaction(bootstrap.IFC4): class TestTransaction(test.bootstrap.IFC4):
def test_that_nothing_happens_without_a_transaction(self): def test_that_nothing_happens_without_a_transaction(self):
wall = self.file.createIfcWall() wall = self.file.createIfcWall()
self.file.undo() self.file.undo()
@@ -134,7 +134,7 @@ class TestTransaction(bootstrap.IFC4):
assert len(list(self.file)) == 2 assert len(list(self.file)) == 2
class TestFile(bootstrap.IFC4): class TestFile(test.bootstrap.IFC4):
def test_creating_a_new_file(self): def test_creating_a_new_file(self):
f = ifcopenshell.file(schema="IFC4") f = ifcopenshell.file(schema="IFC4")
assert f.schema == "IFC4" assert f.schema == "IFC4"
@@ -1,10 +1,10 @@
import pytest import pytest
import bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element import ifcopenshell.util.element
class TestGetPsetsIFC4(bootstrap.IFC4): class TestGetPsetsIFC4(test.bootstrap.IFC4):
def test_getting_the_psets_of_a_product_as_a_dictionary(self): def test_getting_the_psets_of_a_product_as_a_dictionary(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
assert ifcopenshell.util.element.get_psets(element) == {} assert ifcopenshell.util.element.get_psets(element) == {}
@@ -23,7 +23,7 @@ class TestGetPsetsIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_psets(self.file.create_entity("IfcPerson")) == {} assert ifcopenshell.util.element.get_psets(self.file.create_entity("IfcPerson")) == {}
class TestGetPropertyDefinitionIFC4(bootstrap.IFC4): class TestGetPropertyDefinitionIFC4(test.bootstrap.IFC4):
def test_getting_the_properties_of_a_pset(self): def test_getting_the_properties_of_a_pset(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name")
@@ -42,7 +42,7 @@ class TestGetPropertyDefinitionIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_property_definition(pset) == {"LiningDepth": 42} assert ifcopenshell.util.element.get_property_definition(pset) == {"LiningDepth": 42}
class TestGetQuantitiesIFC4(bootstrap.IFC4): class TestGetQuantitiesIFC4(test.bootstrap.IFC4):
def test_getting_quantities_from_a_qto(self): def test_getting_quantities_from_a_qto(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
qto = ifcopenshell.api.run("pset.add_qto", self.file, product=element, name="name") qto = ifcopenshell.api.run("pset.add_qto", self.file, product=element, name="name")
@@ -50,7 +50,7 @@ class TestGetQuantitiesIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_quantities(qto.Quantities) == {"x": 42} assert ifcopenshell.util.element.get_quantities(qto.Quantities) == {"x": 42}
class TestGetPropertiesIFC4(bootstrap.IFC4): class TestGetPropertiesIFC4(test.bootstrap.IFC4):
def test_getting_single_properties_from_a_list_of_properties(self): def test_getting_single_properties_from_a_list_of_properties(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name") pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="name")
@@ -73,7 +73,7 @@ class TestGetPropertiesIFC4(bootstrap.IFC4):
} }
class TestGetTypeIFC4(bootstrap.IFC4): class TestGetTypeIFC4(test.bootstrap.IFC4):
def test_getting_the_type_of_a_product(self): def test_getting_the_type_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
@@ -82,7 +82,7 @@ class TestGetTypeIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_type(element_type) == element_type assert ifcopenshell.util.element.get_type(element_type) == element_type
class TestGetTypeIFC2X3(bootstrap.IFC2X3): class TestGetTypeIFC2X3(test.bootstrap.IFC2X3):
def test_getting_the_type_of_a_product(self): def test_getting_the_type_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType") element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
@@ -91,7 +91,7 @@ class TestGetTypeIFC2X3(bootstrap.IFC2X3):
assert ifcopenshell.util.element.get_type(element_type) == element_type assert ifcopenshell.util.element.get_type(element_type) == element_type
class TestGetMaterial(bootstrap.IFC4): class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_the_material_of_a_product(self): def test_getting_the_material_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
material = ifcopenshell.api.run("material.add_material", self.file) material = ifcopenshell.api.run("material.add_material", self.file)
@@ -158,7 +158,7 @@ class TestGetMaterial(bootstrap.IFC4):
assert ifcopenshell.util.element.get_material(element) == material assert ifcopenshell.util.element.get_material(element) == material
class TestGetContainerIFC4(bootstrap.IFC4): class TestGetContainerIFC4(test.bootstrap.IFC4):
def test_getting_the_spatial_container_of_an_element(self): def test_getting_the_spatial_container_of_an_element(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding") building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
@@ -166,7 +166,7 @@ class TestGetContainerIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_container(element) == building assert ifcopenshell.util.element.get_container(element) == building
class TestGetAggregateIFC4(bootstrap.IFC4): class TestGetAggregateIFC4(test.bootstrap.IFC4):
def test_getting_the_containing_aggregate_of_a_subelement(self): def test_getting_the_containing_aggregate_of_a_subelement(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall") element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcCovering") subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcCovering")
@@ -174,7 +174,7 @@ class TestGetAggregateIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.get_aggregate(subelement) == element assert ifcopenshell.util.element.get_aggregate(subelement) == element
class TestReplaceAttributeIFC4(bootstrap.IFC4): class TestReplaceAttributeIFC4(test.bootstrap.IFC4):
def test_replacing_an_elements_attribute(self): def test_replacing_an_elements_attribute(self):
element = self.file.createIfcWall("foo") element = self.file.createIfcWall("foo")
ifcopenshell.util.element.replace_attribute(element, "foo", "bar") ifcopenshell.util.element.replace_attribute(element, "foo", "bar")
@@ -189,7 +189,7 @@ class TestReplaceAttributeIFC4(bootstrap.IFC4):
assert rel.RelatedObjects == (new,) assert rel.RelatedObjects == (new,)
class TestHasElementReferenceIFC4(bootstrap.IFC4): class TestHasElementReferenceIFC4(test.bootstrap.IFC4):
def test_if_a_element_attribute_references_another_element(self): def test_if_a_element_attribute_references_another_element(self):
old = self.file.createIfcWall() old = self.file.createIfcWall()
new = self.file.createIfcWall() new = self.file.createIfcWall()
@@ -199,7 +199,7 @@ class TestHasElementReferenceIFC4(bootstrap.IFC4):
assert ifcopenshell.util.element.has_element_reference(rel.RelatedObjects, new) is False assert ifcopenshell.util.element.has_element_reference(rel.RelatedObjects, new) is False
class TestRemoveDeepIFC4(bootstrap.IFC4): class TestRemoveDeepIFC4(test.bootstrap.IFC4):
def test_removing_an_element_along_with_all_direct_attributes_recursively(self): def test_removing_an_element_along_with_all_direct_attributes_recursively(self):
owner = self.file.createIfcOwnerHistory() owner = self.file.createIfcOwnerHistory()
element = self.file.createIfcWall(GlobalId="id", OwnerHistory=owner) element = self.file.createIfcWall(GlobalId="id", OwnerHistory=owner)
@@ -219,7 +219,7 @@ class TestRemoveDeepIFC4(bootstrap.IFC4):
assert self.file.by_guid("id2") assert self.file.by_guid("id2")
class TestCopyIFC4(bootstrap.IFC4): class TestCopyIFC4(test.bootstrap.IFC4):
def test_copying_an_element(self): def test_copying_an_element(self):
element = self.file.createIfcWall(GlobalId="id", Name="name") element = self.file.createIfcWall(GlobalId="id", Name="name")
element2 = ifcopenshell.util.element.copy(self.file, element) element2 = ifcopenshell.util.element.copy(self.file, element)
@@ -228,7 +228,7 @@ class TestCopyIFC4(bootstrap.IFC4):
assert element.Name == element2.Name assert element.Name == element2.Name
class TestCopyDeepIFC4(bootstrap.IFC4): class TestCopyDeepIFC4(test.bootstrap.IFC4):
def test_copying_an_element_recursively(self): def test_copying_an_element_recursively(self):
owner = self.file.createIfcOwnerHistory() owner = self.file.createIfcOwnerHistory()
owner.State = "READWRITE" owner.State = "READWRITE"