mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-28 07:49:59 +00:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2dac81ee8d | |||
| 721fe4729a | |||
| 3eb7c7a6a1 | |||
| 2b82eaf019 | |||
| 02a68f6827 | |||
| 2b4d4439ea | |||
| e7a8780828 | |||
| 2dc6a3bcc6 | |||
| 5cee2fb08a | |||
| 8aa790c1c1 | |||
| 2a07f7082a | |||
| 92adeca837 | |||
| 0453db7745 | |||
| 5f29379a6d | |||
| a9f76fc8c0 | |||
| 48cb598975 | |||
| d350a17ce5 | |||
| 9b94c3ceca | |||
| 865c0f4895 | |||
| 95903c965d | |||
| 5b711a23d3 | |||
| 99b776b10e | |||
| ce92aa6e00 | |||
| 33bc0be5ff | |||
| 3004d5424c | |||
| d6aec719e5 | |||
| 55a220751b | |||
| f31ab80731 | |||
| d0eb716738 | |||
| b9084ad0f5 | |||
| 2580cd5e37 | |||
| 177d46b7b6 | |||
| d026fcc900 | |||
| f898893607 | |||
| 6cc842a2ac | |||
| cfc1ddee5e | |||
| 89535e0b6a | |||
| b71684955d | |||
| 81b0442abe | |||
| 88f0938bd2 | |||
| cdd5094d38 | |||
| a1b462a83b | |||
| 41db0f4705 | |||
| 06d3ed7d2a | |||
| 5485177888 | |||
| 8792c6db63 | |||
| 5990d6b66d | |||
| b1b3d7e312 | |||
| 770f35fd97 | |||
| 829ff5e152 | |||
| 4accf30626 |
@@ -26,7 +26,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install dependencies
|
||||
- name: Install C++ dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt-get install --no-install-recommends \
|
||||
@@ -68,14 +68,17 @@ jobs:
|
||||
sudo make -j $(nproc)
|
||||
sudo make install
|
||||
|
||||
- name: install dependencies
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
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 src/bcf
|
||||
sudo /usr/bin/python -m pip install pytest
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd test
|
||||
sudo /usr/bin/python tests.py
|
||||
sudo /usr/bin/python ../src/ifcopenshell-python/ifcopenshell/test_ids.py
|
||||
cd ../src/ifcopenshell-python
|
||||
mv ifcopenshell ifcopenshell-local # Force testing on installed module
|
||||
make test
|
||||
|
||||
@@ -32,8 +32,10 @@ Pipfile.lock
|
||||
|
||||
# gettext binary translation files
|
||||
*.mo
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Flask
|
||||
instance/*
|
||||
@@ -53,3 +55,9 @@ Pipfile.lock
|
||||
# Database
|
||||
*.db
|
||||
|
||||
# PyTest
|
||||
htmlcov
|
||||
.coverage
|
||||
|
||||
# Blender
|
||||
*.blend1
|
||||
|
||||
@@ -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'`
|
||||
PYVERSION:=py37
|
||||
|
||||
@@ -15,11 +33,13 @@ ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/linux-64/hpp-fcl-1.7.5-py37h5f1835d_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/linux-64/eigenpy-2.6.5-py37h95e2c48_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/linux-64/boost-1.74.0-py37h0379df6_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/30/c0/d0526314971fc661b083ab135747dc68446a3022686da8c16d25fcf6ef07/lxml-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/linux-64/hpp-fcl-1.7.5-py39hbcdfc36_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/linux-64/eigenpy-2.6.5-py39h5aed9d1_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/linux-64/boost-1.74.0-py39h5472131_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/19/d9/a69c6aff5673554df48120565a14a50eaa41d29ae03b02faa0b023666318/lxml-4.6.3-cp39-cp39-manylinux2014_x86_64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/linux-64/assimp-5.0.1-hedfc422_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/linux-64/octomap-1.9.7-h4bd325d_0.tar.bz2
|
||||
@@ -31,11 +51,13 @@ ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-64/hpp-fcl-1.7.5-py37h2d7f23a_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/osx-64/eigenpy-2.6.5-py37h0695097_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py37hd79e0ac_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/1e/3e/f0abc15d5dac50939bccc589aae336d5ead4c72e7ad1039a2e0f3630ea92/lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/osx-64/hpp-fcl-1.7.5-py39h1e32b98_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/osx-64/eigenpy-2.6.5-py39h5405915_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/osx-64/boost-1.74.0-py39ha641261_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/b8/74/a71f7ad72e8db54ce899efab84507b801660750cbbfa6a39e6717557d36a/lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/osx-64/assimp-5.0.1-h1224e73_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/osx-64/octomap-1.9.7-h940c156_0.tar.bz2
|
||||
@@ -47,11 +69,13 @@ ifeq ($(PYVERSION), py37)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/win-64/hpp-fcl-1.7.5-py37h839d6b1_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/win-64/eigenpy-2.6.5-py37h2c32e34_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/win-64/boost-1.74.0-py37h3b38789_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/9e/5e/171ee9d40a600f565fe691ec5bf7596247ec62cfb2edc00c91afe8ea837b/lxml-4.6.3-cp37-cp37m-win_amd64.whl
|
||||
endif
|
||||
ifeq ($(PYVERSION), py39)
|
||||
HPPFCL_URL:=https://anaconda.org/conda-forge/hpp-fcl/1.7.5/download/win-64/hpp-fcl-1.7.5-py39h2e7c763_0.tar.bz2
|
||||
EIGENPY_URL:=https://anaconda.org/conda-forge/eigenpy/2.6.5/download/win-64/eigenpy-2.6.5-py39h3ce40e6_0.tar.bz2
|
||||
BOOST_URL:=https://anaconda.org/conda-forge/boost/1.74.0/download/win-64/boost-1.74.0-py39hefe7e4c_3.tar.bz2
|
||||
LXML_URL:=https://files.pythonhosted.org/packages/72/d4/426ecb8849c47c3e370c87aa0ac05d85768df917ffea27fcd6686a5e6495/lxml-4.6.3-cp39-cp39-win_amd64.whl
|
||||
endif
|
||||
ASSIMP_URL:=https://anaconda.org/conda-forge/assimp/5.0.1/download/win-64/assimp-5.0.1-hc2aa0de_6.tar.bz2
|
||||
OCTOMAP_URL:=https://anaconda.org/conda-forge/octomap/1.9.7/download/win-64/octomap-1.9.7-h5362a0b_0.tar.bz2
|
||||
@@ -332,6 +356,13 @@ endif
|
||||
cd dist/working/ && patch ../blenderbim/libs/site/packages/behave/runner_util.py < runner_util.patch
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by ids
|
||||
mkdir dist/working
|
||||
cd dist/working && wget $(LXML_URL)
|
||||
cd dist/working && cp *.whl lxml.zip && unzip lxml.zip
|
||||
cp -r dist/working/lxml dist/blenderbim/libs/site/packages/
|
||||
rm -rf dist/working
|
||||
|
||||
# Required by behave
|
||||
mkdir dist/working
|
||||
cd dist/working && wget https://files.pythonhosted.org/packages/f4/65/220bb4075fddb09d5b3ea2c1c1fa66c1c72be9361ec187aab50fa161e576/parse-1.15.0.tar.gz
|
||||
@@ -413,6 +444,35 @@ endif
|
||||
cd dist && zip -r blenderbim-$(VERSION)-$(PYVERSION)-$(PLATFORM).zip ./*
|
||||
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: qa
|
||||
qa:
|
||||
black .
|
||||
pylint ./* --output-format=colorized --disable all --enable E --disable import-error
|
||||
|
||||
.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
|
||||
clean:
|
||||
rm -rf dist
|
||||
rm -rf htmlcov
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -17,10 +16,14 @@
|
||||
# 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 os
|
||||
import sys
|
||||
import site
|
||||
|
||||
bl_info = {
|
||||
"name": "BlenderBIM",
|
||||
"description": "Author, import, and export files in the " "Industry Foundation Classes (.ifc) file format",
|
||||
"author": "Dion Moult, IfcOpenShell",
|
||||
"description": "Author, import, and export data using the Industry Foundation Classes schema",
|
||||
"author": "IfcOpenShell Contributors",
|
||||
"blender": (2, 80, 0),
|
||||
"version": (0, 0, 999999),
|
||||
"location": "File > Export, File > Import, Scene / Object / Material / Mesh Properties",
|
||||
@@ -28,25 +31,15 @@ bl_info = {
|
||||
"category": "Import-Export",
|
||||
}
|
||||
|
||||
import os
|
||||
import site
|
||||
if sys.modules.get("bpy", None):
|
||||
# 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
|
||||
# 3 levels deep required by occ static ../../ path
|
||||
# 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 register():
|
||||
blenderbim.bim.register()
|
||||
|
||||
|
||||
# main import
|
||||
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()
|
||||
def unregister():
|
||||
blenderbim.bim.unregister()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -17,157 +16,152 @@
|
||||
# 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/>.
|
||||
|
||||
# Check if we are running in Blender before loading, to allow for multiprocessing
|
||||
import sys
|
||||
import bpy
|
||||
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:
|
||||
import bpy
|
||||
import importlib
|
||||
from . import handler, ui, prop, operator
|
||||
for name in modules.keys():
|
||||
modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}")
|
||||
|
||||
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,
|
||||
}
|
||||
classes = [
|
||||
operator.OpenUri,
|
||||
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.SnapSpacesTogether,
|
||||
operator.OverrideDelete,
|
||||
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 name in modules.keys():
|
||||
modules[name] = importlib.import_module(f"blenderbim.bim.module.{name}")
|
||||
for mod in modules.values():
|
||||
classes.extend(mod.classes)
|
||||
|
||||
classes = [
|
||||
operator.OpenUri,
|
||||
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():
|
||||
classes.extend(module.classes)
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)")
|
||||
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(operator.ExportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcjson)")
|
||||
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)")
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(operator.ImportIFC.bl_idname, text="Industry Foundation Classes (.ifc/.ifczip/.ifcxml)")
|
||||
|
||||
def on_register(scene):
|
||||
handler.setDefaultProperties(scene)
|
||||
bpy.app.handlers.depsgraph_update_post.remove(on_register)
|
||||
|
||||
def register():
|
||||
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.Collection.BIMObjectProperties = bpy.props.PointerProperty(
|
||||
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)
|
||||
def on_register(scene):
|
||||
handler.setDefaultProperties(scene)
|
||||
bpy.app.handlers.depsgraph_update_post.remove(on_register)
|
||||
|
||||
for module in modules.values():
|
||||
module.register()
|
||||
|
||||
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)
|
||||
def register():
|
||||
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)
|
||||
|
||||
for module in reversed(list(modules.values())):
|
||||
module.unregister()
|
||||
for mod in modules.values():
|
||||
mod.register()
|
||||
|
||||
|
||||
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.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 mod in reversed(list(modules.values())):
|
||||
mod.unregister()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -114,7 +113,7 @@ class IfcExporter:
|
||||
IfcStore.edited_objs.clear()
|
||||
|
||||
def sync_object_placement(self, obj):
|
||||
blender_matrix = np.matrix(obj.matrix_world)
|
||||
blender_matrix = np.array(obj.matrix_world)
|
||||
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
if not hasattr(element, "ObjectPlacement"):
|
||||
return
|
||||
@@ -158,7 +157,6 @@ class IfcExporter:
|
||||
else:
|
||||
parent_collection = obj.users_collection[0]
|
||||
|
||||
|
||||
parent_obj = bpy.data.objects.get(parent_collection.name)
|
||||
if not parent_obj or not parent_obj.BIMObjectProperties.ifc_definition_id:
|
||||
return
|
||||
@@ -174,6 +172,7 @@ class IfcExporter:
|
||||
try:
|
||||
# This will throw an exception if the Blender object no longer exists
|
||||
foo = obj.name
|
||||
foo
|
||||
return False
|
||||
except:
|
||||
return True
|
||||
@@ -201,7 +200,6 @@ class IfcExportSettings:
|
||||
|
||||
@staticmethod
|
||||
def factory(context, output_file, logger):
|
||||
scene_bim = context.scene.BIMProperties
|
||||
settings = IfcExportSettings()
|
||||
settings.output_file = output_file
|
||||
settings.logger = logger
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -19,8 +18,11 @@
|
||||
|
||||
import bpy
|
||||
import uuid
|
||||
import zipfile
|
||||
import tempfile
|
||||
import ifcopenshell
|
||||
import blenderbim.bim.handler
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class IfcStore:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -17,31 +16,23 @@
|
||||
# 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 ifcopenshell
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.selector
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
import bpy
|
||||
import bmesh
|
||||
import os
|
||||
import re
|
||||
import bpy
|
||||
import time
|
||||
import bmesh
|
||||
import shutil
|
||||
import threading
|
||||
import json
|
||||
import time
|
||||
import mathutils
|
||||
import math
|
||||
import multiprocessing
|
||||
import zipfile
|
||||
import tempfile
|
||||
import numpy as np
|
||||
from blenderbim.bim.module.drawing.prop import getDiagramScales
|
||||
from pathlib import Path
|
||||
from itertools import cycle
|
||||
from datetime import datetime
|
||||
import multiprocessing
|
||||
import ifcopenshell
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.selector
|
||||
import ifcopenshell.util.geolocation
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.drawing.prop import get_diagram_scales
|
||||
|
||||
|
||||
class FileCopy(threading.Thread):
|
||||
@@ -172,12 +163,10 @@ class IfcImporter:
|
||||
self.settings_native.set(self.settings_native.INCLUDE_CURVES, True)
|
||||
self.settings_2d = ifcopenshell.geom.settings()
|
||||
self.settings_2d.set(self.settings_2d.INCLUDE_CURVES, True)
|
||||
self.filter_mode = None
|
||||
self.include_elements = set()
|
||||
self.exclude_elements = set()
|
||||
self.iterator_elements = set()
|
||||
self.project = None
|
||||
self.spatial_structure_elements = {}
|
||||
self.elements = []
|
||||
self.elements = set()
|
||||
self.type_collection = None
|
||||
self.type_products = {}
|
||||
self.openings = {}
|
||||
@@ -208,10 +197,6 @@ class IfcImporter:
|
||||
bpy.context.window_manager.progress_begin(0, 100)
|
||||
self.progress = 0
|
||||
self.profile_code("Starting import process")
|
||||
self.load_diff()
|
||||
self.profile_code("Load diff")
|
||||
self.purge_diff()
|
||||
self.profile_code("Purge diffs")
|
||||
self.load_file()
|
||||
self.profile_code("Loading file")
|
||||
self.calculate_unit_scale()
|
||||
@@ -222,14 +207,10 @@ class IfcImporter:
|
||||
self.profile_code("Set units")
|
||||
self.create_project()
|
||||
self.profile_code("Create project")
|
||||
self.create_spatial_hierarchy()
|
||||
self.profile_code("Create spatial hierarchy")
|
||||
self.process_element_filter()
|
||||
self.profile_code("Process element filter")
|
||||
self.create_aggregates()
|
||||
self.profile_code("Create aggregates")
|
||||
self.create_aggregate_tree()
|
||||
self.profile_code("Create aggregate tree")
|
||||
self.create_collections()
|
||||
self.profile_code("Create collections")
|
||||
self.create_openings_collection()
|
||||
self.profile_code("Create opening collection")
|
||||
self.create_materials()
|
||||
@@ -260,9 +241,7 @@ class IfcImporter:
|
||||
elif self.ifc_import_settings.should_merge_by_material:
|
||||
self.merge_by_material()
|
||||
self.profile_code("Merging by material")
|
||||
if self.ifc_import_settings.should_merge_materials_by_colour or (
|
||||
self.ifc_import_settings.should_auto_set_workarounds and len(self.material_creator.materials) > 300
|
||||
):
|
||||
if self.ifc_import_settings.should_merge_materials_by_colour or len(self.material_creator.materials) > 300:
|
||||
self.merge_materials_by_colour()
|
||||
self.profile_code("Merging by colour")
|
||||
self.add_project_to_scene()
|
||||
@@ -290,32 +269,17 @@ class IfcImporter:
|
||||
return abs(coords[0]) > limit or abs(coords[1]) > limit or abs(coords[2]) > limit
|
||||
|
||||
def process_element_filter(self):
|
||||
if self.ifc_import_settings.ifc_import_filter == "NONE" or not self.ifc_import_settings.ifc_selector:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
return
|
||||
|
||||
selector = ifcopenshell.util.selector.Selector()
|
||||
elements = selector.parse(self.file, self.ifc_import_settings.ifc_selector)
|
||||
if self.ifc_import_settings.ifc_import_filter == "WHITELIST":
|
||||
self.filter_mode = "WHITELIST"
|
||||
self.include_elements = set(elements)
|
||||
self.elements = self.include_elements
|
||||
elif self.ifc_import_settings.ifc_import_filter == "BLACKLIST":
|
||||
self.filter_mode = "BLACKLIST"
|
||||
self.exclude_elements = set(elements)
|
||||
self.elements = [e for e in self.file.by_type("IfcElement") if e not in self.exclude_elements]
|
||||
if self.ifc_import_settings.has_filter:
|
||||
self.elements = set(self.ifc_import_settings.elements)
|
||||
else:
|
||||
self.elements = set(self.file.by_type("IfcElement"))
|
||||
self.iterator_elements = set(self.elements)
|
||||
|
||||
def parse_native_elements(self):
|
||||
if self.filter_mode == "WHITELIST":
|
||||
for element in self.include_elements:
|
||||
if self.is_native(element):
|
||||
self.native_elements[element.GlobalId] = element
|
||||
self.include_elements -= self.native_elements
|
||||
elif self.filter_mode == "BLACKLIST":
|
||||
for element in set(self.file.by_type("IfcElement")) - self.exclude_elements:
|
||||
if self.is_native(element):
|
||||
self.native_elements.add(element)
|
||||
self.exclude_elements |= self.native_elements
|
||||
for element in self.elements:
|
||||
if self.is_native(element):
|
||||
self.native_elements.add(element)
|
||||
self.iterator_elements -= self.native_elements
|
||||
|
||||
def is_native(self, element):
|
||||
if (
|
||||
@@ -408,7 +372,6 @@ class IfcImporter:
|
||||
props.has_blender_offset = True
|
||||
|
||||
def get_offset_point(self):
|
||||
offset_point = None
|
||||
elements_checked = 0
|
||||
# If more than these points aren't far away, the file probably isn't absolutely positioned
|
||||
element_checking_threshold = 100
|
||||
@@ -444,31 +407,33 @@ class IfcImporter:
|
||||
if props.has_blender_offset:
|
||||
if self.is_point_far_away((matrix[0, 3], matrix[1, 3], matrix[2, 3])):
|
||||
obj.BIMObjectProperties.blender_offset_type = "OBJECT_PLACEMENT"
|
||||
return mathutils.Matrix(
|
||||
ifcopenshell.util.geolocation.global2local(
|
||||
matrix,
|
||||
float(props.blender_eastings) * self.unit_scale,
|
||||
float(props.blender_northings) * self.unit_scale,
|
||||
float(props.blender_orthogonal_height) * self.unit_scale,
|
||||
float(props.blender_x_axis_abscissa),
|
||||
float(props.blender_x_axis_ordinate),
|
||||
).tolist()
|
||||
matrix = ifcopenshell.util.geolocation.global2local(
|
||||
matrix,
|
||||
float(props.blender_eastings) * self.unit_scale,
|
||||
float(props.blender_northings) * self.unit_scale,
|
||||
float(props.blender_orthogonal_height) * self.unit_scale,
|
||||
float(props.blender_x_axis_abscissa),
|
||||
float(props.blender_x_axis_ordinate),
|
||||
)
|
||||
else:
|
||||
obj.BIMObjectProperties.blender_offset_type = "CARTESIAN_POINT"
|
||||
|
||||
if self.ifc_import_settings.should_offset_model:
|
||||
matrix[0, 3] += self.ifc_import_settings.model_offset_coordinates[0]
|
||||
matrix[1, 3] += self.ifc_import_settings.model_offset_coordinates[1]
|
||||
matrix[2, 3] += self.ifc_import_settings.model_offset_coordinates[2]
|
||||
|
||||
return mathutils.Matrix(matrix.tolist())
|
||||
|
||||
def find_decomposed_ifc_class(self, element, ifc_class):
|
||||
results = []
|
||||
if element.is_a(ifc_class):
|
||||
return element
|
||||
rel_aggregates = element.IsDecomposedBy
|
||||
if not rel_aggregates:
|
||||
return results
|
||||
for rel_aggregate in rel_aggregates:
|
||||
for part in rel_aggregate.RelatedObjects:
|
||||
if part.is_a(ifc_class):
|
||||
results.append(part)
|
||||
results.extend(self.find_decomposed_ifc_class(part, ifc_class))
|
||||
return results
|
||||
result = self.find_decomposed_ifc_class(part, ifc_class)
|
||||
if result:
|
||||
return result
|
||||
|
||||
def create_grids(self):
|
||||
grids = self.file.by_type("IfcGrid")
|
||||
@@ -511,7 +476,7 @@ class IfcImporter:
|
||||
self.type_collection = bpy.data.collections.new("Types")
|
||||
self.project["blender"].children.link(self.type_collection)
|
||||
|
||||
if self.filter_mode in ["WHITELIST", "BLACKLIST"]:
|
||||
if self.ifc_import_settings.has_filter:
|
||||
type_products = set([ifcopenshell.util.element.get_type(e) for e in self.elements])
|
||||
else:
|
||||
type_products = self.file.by_type("IfcTypeProduct")
|
||||
@@ -590,24 +555,23 @@ class IfcImporter:
|
||||
print("Done creating geometry")
|
||||
|
||||
def create_products(self):
|
||||
if self.ifc_import_settings.has_filter and not self.iterator_elements:
|
||||
return
|
||||
if self.ifc_import_settings.should_use_cpu_multiprocessing:
|
||||
iterator = ifcopenshell.geom.iterator(
|
||||
self.settings,
|
||||
self.file,
|
||||
multiprocessing.cpu_count(),
|
||||
include=self.include_elements or None,
|
||||
exclude=self.exclude_elements or None,
|
||||
include=self.iterator_elements or None,
|
||||
)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(
|
||||
self.settings, self.file, include=self.include_elements or None, exclude=self.exclude_elements or None
|
||||
)
|
||||
iterator = ifcopenshell.geom.iterator(self.settings, self.file, include=self.iterator_elements or None)
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return False
|
||||
checkpoint = time.time()
|
||||
total_created = 0
|
||||
approx_total_products = len(self.include_elements) or len(self.file.by_type("IfcElement"))
|
||||
approx_total_products = len(self.iterator_elements) or len(self.file.by_type("IfcElement"))
|
||||
start_progress = self.progress
|
||||
progress_range = 85 - start_progress
|
||||
while True:
|
||||
@@ -747,7 +711,7 @@ class IfcImporter:
|
||||
if shape:
|
||||
m = shape.transformation.matrix.data
|
||||
# We use numpy here because Blender mathutils.Matrix is not accurate enough
|
||||
mat = np.matrix(
|
||||
mat = np.array(
|
||||
([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1])
|
||||
)
|
||||
obj.matrix_world = self.apply_blender_offset_to_matrix_world(obj, mat)
|
||||
@@ -960,15 +924,10 @@ class IfcImporter:
|
||||
return
|
||||
self.openings[element.GlobalId] = obj
|
||||
|
||||
def load_diff(self):
|
||||
if not self.ifc_import_settings.diff_file:
|
||||
return
|
||||
with open(self.ifc_import_settings.diff_file, "r") as file:
|
||||
self.diff = json.load(file)
|
||||
|
||||
def load_file(self):
|
||||
self.ifc_import_settings.logger.info("loading file %s", self.ifc_import_settings.input_file)
|
||||
bpy.context.scene.BIMProperties.ifc_file = self.ifc_import_settings.input_file
|
||||
if not bpy.context.scene.BIMProperties.ifc_file:
|
||||
bpy.context.scene.BIMProperties.ifc_file = self.ifc_import_settings.input_file
|
||||
self.file = IfcStore.get_file()
|
||||
|
||||
def calculate_unit_scale(self):
|
||||
@@ -1004,10 +963,7 @@ class IfcImporter:
|
||||
)
|
||||
|
||||
def create_project(self):
|
||||
if self.file.schema == "IFC2X3":
|
||||
self.project = {"ifc": self.file.by_type("IfcProject")[0]}
|
||||
else:
|
||||
self.project = {"ifc": self.file.by_type("IfcContext")[0]}
|
||||
self.project = {"ifc": self.file.by_type("IfcProject")[0]}
|
||||
self.project["blender"] = bpy.data.collections.new(
|
||||
"{}/{}".format(self.project["ifc"].is_a(), self.project["ifc"].Name)
|
||||
)
|
||||
@@ -1015,13 +971,32 @@ class IfcImporter:
|
||||
if obj:
|
||||
self.project["blender"].objects.link(obj)
|
||||
|
||||
def create_spatial_hierarchy(self):
|
||||
if self.project["ifc"].IsDecomposedBy:
|
||||
for rel_aggregate in self.project["ifc"].IsDecomposedBy:
|
||||
self.add_related_objects(self.project["blender"], rel_aggregate.RelatedObjects)
|
||||
def create_collections(self):
|
||||
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
|
||||
self.create_decomposition_collections()
|
||||
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
|
||||
self.create_spatial_decomposition_collections()
|
||||
|
||||
def create_decomposition_collections(self):
|
||||
self.create_spatial_decomposition_collections()
|
||||
self.create_aggregate_collections()
|
||||
|
||||
def create_spatial_decomposition_collections(self):
|
||||
containers = set([ifcopenshell.util.element.get_container(e) for e in self.elements])
|
||||
self.decomposition_containers = set()
|
||||
for container in containers:
|
||||
while container:
|
||||
self.decomposition_containers.add(container)
|
||||
container = ifcopenshell.util.element.get_aggregate(container)
|
||||
if container and container.is_a("IfcContext"):
|
||||
container = None
|
||||
for rel_aggregate in self.project["ifc"].IsDecomposedBy or []:
|
||||
self.add_related_objects(self.project["blender"], rel_aggregate.RelatedObjects)
|
||||
|
||||
def add_related_objects(self, parent, related_objects):
|
||||
for element in related_objects:
|
||||
if element not in self.decomposition_containers:
|
||||
continue
|
||||
global_id = element.GlobalId
|
||||
collection = bpy.data.collections.new(self.get_name(element))
|
||||
self.spatial_structure_elements[global_id] = {"blender": collection}
|
||||
@@ -1034,18 +1009,23 @@ class IfcImporter:
|
||||
for rel_aggregate in element.IsDecomposedBy:
|
||||
self.add_related_objects(collection, rel_aggregate.RelatedObjects)
|
||||
|
||||
def create_aggregate_collections(self):
|
||||
self.create_aggregates()
|
||||
self.create_aggregate_tree()
|
||||
|
||||
def create_aggregates(self):
|
||||
if self.filter_mode in ["WHITELIST", "BLACKLIST"]:
|
||||
rel_aggregates = [e.IsDecomposedBy[0].RelatingObject for e in self.elements if e.IsDecomposedBy]
|
||||
if self.ifc_import_settings.has_filter:
|
||||
rel_aggregates = [e.IsDecomposedBy[0] for e in self.elements if e.IsDecomposedBy]
|
||||
else:
|
||||
rel_aggregates = [a for a in self.file.by_type("IfcRelAggregates") if a.RelatingObject.is_a("IfcElement")]
|
||||
|
||||
if len(rel_aggregates) > 10000:
|
||||
# More than 10,000 collections makes Blender unhappy
|
||||
print("Falling back to SPATIAL_DECOMPOSITION collection mode")
|
||||
self.ifc_import_settings.collection_mode = "SPATIAL_DECOMPOSITION"
|
||||
else:
|
||||
for rel_aggregate in rel_aggregates:
|
||||
self.create_aggregate(rel_aggregate)
|
||||
print("Skipping aggregate collections for performance.")
|
||||
return
|
||||
|
||||
for rel_aggregate in rel_aggregates:
|
||||
self.create_aggregate(rel_aggregate)
|
||||
|
||||
def create_aggregate_tree(self):
|
||||
for aggregate in self.aggregates.values():
|
||||
@@ -1135,18 +1115,6 @@ class IfcImporter:
|
||||
def get_name(self, element):
|
||||
return "{}/{}".format(element.is_a(), element.Name)
|
||||
|
||||
def purge_diff(self):
|
||||
if not self.diff:
|
||||
return
|
||||
objects_to_purge = []
|
||||
for obj in bpy.data.objects:
|
||||
if "GlobalId" not in obj.BIMObjectProperties.attributes:
|
||||
continue
|
||||
global_id = obj.BIMObjectProperties.attributes["GlobalId"].string_value
|
||||
if global_id in self.diff["deleted"] or global_id in self.diff["changed"].keys():
|
||||
objects_to_purge.append(obj)
|
||||
bpy.ops.object.delete({"selected_objects": objects_to_purge})
|
||||
|
||||
def place_objects_in_spatial_tree(self):
|
||||
for ifc_definition_id, obj in self.added_data.items():
|
||||
if isinstance(obj, bpy.types.Object):
|
||||
@@ -1344,7 +1312,7 @@ class IfcImporter:
|
||||
if "TargetView" in pset:
|
||||
camera.BIMCameraProperties.target_view = pset["TargetView"]
|
||||
if "Scale" in pset:
|
||||
valid_scales = [i[0] for i in getDiagramScales(None, None) if pset["Scale"] == i[0].split("|")[-1]]
|
||||
valid_scales = [i[0] for i in get_diagram_scales(None, bpy.context) if pset["Scale"] == i[0].split("|")[-1]]
|
||||
if valid_scales:
|
||||
camera.BIMCameraProperties.diagram_scale = valid_scales[0]
|
||||
else:
|
||||
@@ -1391,13 +1359,7 @@ class IfcImporter:
|
||||
num_vertex_indices = len(geometry.faces)
|
||||
|
||||
mesh.vertices.add(num_vertices)
|
||||
if self.ifc_import_settings.should_offset_model:
|
||||
# Potentially, there is a smarter way to do this. See #1047
|
||||
v_index = cycle((0, 1, 2))
|
||||
verts = [v + self.ifc_import_settings.model_offset_coordinates[next(v_index)] for v in verts]
|
||||
mesh.vertices.foreach_set("co", verts)
|
||||
else:
|
||||
mesh.vertices.foreach_set("co", verts)
|
||||
mesh.vertices.foreach_set("co", verts)
|
||||
mesh.loops.add(num_vertex_indices)
|
||||
mesh.loops.foreach_set("vertex_index", geometry.faces)
|
||||
mesh.polygons.add(num_loops)
|
||||
@@ -1472,7 +1434,6 @@ class IfcImportSettings:
|
||||
self.logger = None
|
||||
self.input_file = None
|
||||
self.diff_file = None
|
||||
self.should_auto_set_workarounds = True
|
||||
self.should_use_cpu_multiprocessing = True
|
||||
self.should_merge_by_class = False
|
||||
self.should_merge_by_material = False
|
||||
@@ -1482,13 +1443,12 @@ class IfcImportSettings:
|
||||
self.angular_tolerance = 0.5
|
||||
self.should_offset_model = False
|
||||
self.model_offset_coordinates = (0, 0, 0)
|
||||
self.ifc_import_filter = "NONE"
|
||||
self.ifc_selector = ""
|
||||
self.has_filter = None
|
||||
self.elements = ""
|
||||
self.collection_mode = "DECOMPOSITION"
|
||||
|
||||
@staticmethod
|
||||
def factory(context, input_file, logger):
|
||||
scene_bim = context.scene.BIMProperties
|
||||
scene_diff = context.scene.DiffProperties
|
||||
settings = IfcImportSettings()
|
||||
settings.input_file = input_file
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# 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/>.
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -56,7 +55,9 @@ class BIM_PT_aggregate(Panel):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "relating_object", text="")
|
||||
if props.relating_object:
|
||||
row.operator("bim.assign_object", icon="CHECKMARK", text="").relating_object = props.relating_object.name
|
||||
row.operator(
|
||||
"bim.assign_object", icon="CHECKMARK", text=""
|
||||
).relating_object = props.relating_object.name
|
||||
row.operator("bim.disable_editing_aggregate", icon="CANCEL", text="")
|
||||
else:
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -119,9 +118,7 @@ class EditAttributes(bpy.types.Operator):
|
||||
elif attribute["type"] == "enum":
|
||||
attributes[attribute["name"]] = blender_attribute.enum_value
|
||||
product = self.file.by_id(oprops.ifc_definition_id)
|
||||
ifcopenshell.api.run(
|
||||
"attribute.edit_attributes", self.file, **{"product": product, "attributes": attributes}
|
||||
)
|
||||
ifcopenshell.api.run("attribute.edit_attributes", self.file, **{"product": product, "attributes": attributes})
|
||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||
bpy.ops.bim.disable_editing_attributes(obj=obj.name, obj_type=self.obj_type)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -32,6 +31,7 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
)
|
||||
|
||||
|
||||
class BIMAttributeProperties(PropertyGroup):
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
is_editing_attributes: BoolProperty(name="Is Editing Attributes")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -68,6 +67,7 @@ class AuginCreateNewModel(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
import boto3
|
||||
from botocore.config import Config
|
||||
|
||||
props = context.scene.AuginProperties
|
||||
|
||||
# Create project
|
||||
@@ -135,7 +135,6 @@ class AuginCreateNewModel(bpy.types.Operator):
|
||||
client.upload_file(context.scene.BIMProperties.ifc_file, result["s3_bucket"], result["model_path"])
|
||||
client.upload_file(thumb_path, result["s3_bucket"], result["thumb_path"])
|
||||
|
||||
|
||||
# Notify done
|
||||
url = "https://server.auge.pro.br/API/v3/augin_rest.php/files_uploaded"
|
||||
payload = {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -20,6 +19,7 @@
|
||||
import bcf
|
||||
import bcf.v2.bcfxml
|
||||
|
||||
|
||||
class BcfStore:
|
||||
bcfxml = None
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -31,6 +30,7 @@ from blenderbim.bim.ifc import IfcStore
|
||||
from math import radians, degrees, atan, tan, cos, sin
|
||||
from mathutils import Vector, Matrix, Euler, geometry
|
||||
|
||||
|
||||
class NewBcfProject(bpy.types.Operator):
|
||||
bl_idname = "bim.new_bcf_project"
|
||||
bl_label = "New BCF Project"
|
||||
@@ -79,7 +79,7 @@ class LoadBcfTopics(bpy.types.Operator):
|
||||
context.scene.BCFProperties.topics.clear()
|
||||
for index, topic_guid in enumerate(bcfxml.topics.keys()):
|
||||
new = context.scene.BCFProperties.topics.add()
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic_guid, topic_index = index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic_guid, topic_index=index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
"modified_author": topic.modified_author,
|
||||
"assigned_to": topic.assigned_to,
|
||||
"due_date": topic.due_date,
|
||||
"description": topic.description
|
||||
"description": topic.description,
|
||||
}
|
||||
for key, value in data_map.items():
|
||||
if value is not None:
|
||||
@@ -128,7 +128,7 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
"type": topic.bim_snippet.snippet_type,
|
||||
"is_external": topic.bim_snippet.is_external,
|
||||
"reference": topic.bim_snippet.reference,
|
||||
"schema": topic.bim_snippet.reference_schema
|
||||
"schema": topic.bim_snippet.reference_schema,
|
||||
}
|
||||
for key, value in data_map.items():
|
||||
if value is not None:
|
||||
@@ -141,7 +141,7 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
"reference": doc.referenced_document,
|
||||
"description": doc.description,
|
||||
"guid": doc.guid,
|
||||
"is_external": doc.is_external
|
||||
"is_external": doc.is_external,
|
||||
}
|
||||
for key, value in data_map.items():
|
||||
if value is not None:
|
||||
@@ -152,7 +152,7 @@ class LoadBcfTopic(bpy.types.Operator):
|
||||
new_related_topic = new.related_topics.add()
|
||||
new_related_topic.name = related_topic.guid
|
||||
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid = topic.guid)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -287,11 +287,12 @@ class AddBcfBimSnippet(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return all((getattr(context.scene.BCFProperties, attr, False) for attr in (
|
||||
"bim_snippet_reference",
|
||||
"bim_snippet_schema",
|
||||
"bim_snippet_type"
|
||||
)))
|
||||
return all(
|
||||
(
|
||||
getattr(context.scene.BCFProperties, attr, False)
|
||||
for attr in ("bim_snippet_reference", "bim_snippet_schema", "bim_snippet_type")
|
||||
)
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
@@ -303,7 +304,7 @@ class AddBcfBimSnippet(bpy.types.Operator):
|
||||
bim_snippet.reference_schema = props.bim_snippet_schema
|
||||
bim_snippet.snippet_type = props.bim_snippet_type
|
||||
bcfxml.add_bim_snippet(topic, bim_snippet)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
bim_snippet.reference = ""
|
||||
bim_snippet.reference_schema = ""
|
||||
bim_snippet.snippet_type = ""
|
||||
@@ -316,7 +317,7 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
def poll(cls, context):
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
props = context.scene.BCFProperties
|
||||
blender_topic = props.active_topic
|
||||
@@ -347,7 +348,7 @@ class AddBcfRelatedTopic(bpy.types.Operator):
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic.related_topics.append(related_topic)
|
||||
bcfxml.edit_topic(topic)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.related_topic = ""
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -516,7 +517,7 @@ class AddBcfReferenceLink(bpy.types.Operator):
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
topic.reference_links.append(props.reference_link)
|
||||
bcfxml.edit_topic(topic)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.reference_link = ""
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -539,7 +540,7 @@ class AddBcfDocumentReference(bpy.types.Operator):
|
||||
document_reference.referenced_document = props.document_reference
|
||||
document_reference.description = props.document_reference_description or None
|
||||
bcfxml.add_document_reference(topic, document_reference)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
props.document_reference = ""
|
||||
props.document_reference_description = ""
|
||||
return {"FINISHED"}
|
||||
@@ -668,7 +669,7 @@ class RemoveBcfDocumentReference(bpy.types.Operator):
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_document_reference(topic, self.index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -685,7 +686,7 @@ class RemoveBcfRelatedTopic(bpy.types.Operator):
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
del topic.related_topics[self.index]
|
||||
bcfxml.edit_topic(topic)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid = topic.guid, topic_index = props.active_topic_index)
|
||||
bpy.ops.bim.load_bcf_topic(topic_guid=topic.guid, topic_index=props.active_topic_index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -701,7 +702,7 @@ class RemoveBcfComment(bpy.types.Operator):
|
||||
blender_topic = props.active_topic
|
||||
topic = bcfxml.topics[blender_topic.name]
|
||||
bcfxml.delete_comment(self.comment_guid, topic)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid = topic.guid)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -720,7 +721,7 @@ class EditBcfComment(bpy.types.Operator):
|
||||
comment = topic.comments[self.comment_guid]
|
||||
comment.comment = blender_comment.comment
|
||||
bcfxml.edit_comment(comment, topic)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid = topic.guid)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -750,7 +751,7 @@ class AddBcfComment(bpy.types.Operator):
|
||||
comment.viewpoint = bcf.v2.data.Viewpoint()
|
||||
comment.viewpoint.guid = blender_topic.viewpoints
|
||||
bcfxml.add_comment(topic, comment)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid = topic.guid)
|
||||
bpy.ops.bim.load_bcf_comments(topic_guid=topic.guid)
|
||||
props.comment = ""
|
||||
props.has_related_viewpoint = False
|
||||
return {"FINISHED"}
|
||||
@@ -787,14 +788,12 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
cam_width = context.scene.render.resolution_x
|
||||
cam_height = context.scene.render.resolution_y
|
||||
cam_aspect = cam_width / cam_height
|
||||
|
||||
|
||||
if viewpoint.snapshot:
|
||||
obj.data.show_background_images = True
|
||||
obj.data.background_images.clear()
|
||||
background = obj.data.background_images.new()
|
||||
background.image = bpy.data.images.load(
|
||||
os.path.join(bcfxml.filepath, topic.guid, viewpoint.snapshot)
|
||||
)
|
||||
background.image = bpy.data.images.load(os.path.join(bcfxml.filepath, topic.guid, viewpoint.snapshot))
|
||||
src_width = background.image.size[0]
|
||||
src_height = background.image.size[1]
|
||||
src_aspect = src_width / src_height
|
||||
@@ -839,19 +838,25 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
obj.data.angle = radians(camera.field_of_view)
|
||||
else:
|
||||
# https://blender.stackexchange.com/questions/23431/how-to-set-camera-horizontal-and-vertical-fov
|
||||
obj.data.angle = 2 * atan((0.5 * cam_height) / (0.5 * cam_width / tan(radians(camera.field_of_view) / 2)))
|
||||
obj.data.angle = 2 * atan(
|
||||
(0.5 * cam_height) / (0.5 * cam_width / tan(radians(camera.field_of_view) / 2))
|
||||
)
|
||||
|
||||
z_axis = Vector((-camera.camera_direction.x, -camera.camera_direction.y, -camera.camera_direction.z)).normalized()
|
||||
z_axis = Vector(
|
||||
(-camera.camera_direction.x, -camera.camera_direction.y, -camera.camera_direction.z)
|
||||
).normalized()
|
||||
y_axis = Vector((camera.camera_up_vector.x, camera.camera_up_vector.y, camera.camera_up_vector.z)).normalized()
|
||||
x_axis = y_axis.cross(z_axis).normalized()
|
||||
rotation = Matrix((x_axis, y_axis, z_axis))
|
||||
rotation.invert()
|
||||
matrix = np.matrix((
|
||||
[x_axis[0], y_axis[0], z_axis[0], camera.camera_view_point.x],
|
||||
[x_axis[1], y_axis[1], z_axis[1], camera.camera_view_point.y],
|
||||
[x_axis[2], y_axis[2], z_axis[2], camera.camera_view_point.z],
|
||||
[0, 0, 0, 1],
|
||||
))
|
||||
matrix = np.matrix(
|
||||
(
|
||||
[x_axis[0], y_axis[0], z_axis[0], camera.camera_view_point.x],
|
||||
[x_axis[1], y_axis[1], z_axis[1], camera.camera_view_point.y],
|
||||
[x_axis[2], y_axis[2], z_axis[2], camera.camera_view_point.z],
|
||||
[0, 0, 0, 1],
|
||||
)
|
||||
)
|
||||
props = context.scene.BIMGeoreferenceProperties
|
||||
if props.has_blender_offset:
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||
@@ -961,7 +966,9 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
stroke.points.add(len(viewpoint.lines) * 2)
|
||||
coords = []
|
||||
for l in viewpoint.lines:
|
||||
coords.extend([l.start_point.x, l.start_point.y, l.start_point.z, l.end_point.x, l.end_point.y, l.end_point.z])
|
||||
coords.extend(
|
||||
[l.start_point.x, l.start_point.y, l.start_point.z, l.end_point.x, l.end_point.y, l.end_point.z]
|
||||
)
|
||||
stroke.points.foreach_set("co", coords)
|
||||
|
||||
def create_clipping_planes(self, viewpoint):
|
||||
@@ -1025,6 +1032,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
t = tuple(int(value[i : i + lv // 3], 16) for i in range(0, lv, lv // 3))
|
||||
return [t[0] / 255.0, t[1] / 255.0, t[2] / 255.0, 1]
|
||||
|
||||
|
||||
class OpenBcfReferenceLink(bpy.types.Operator):
|
||||
bl_idname = "bim.open_bcf_reference_link"
|
||||
bl_label = "Open BCF Reference Link"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -73,7 +72,7 @@ def updateBcfTopicIsEditable(self, context):
|
||||
|
||||
def updateBcfCommentIsEditable(self, context):
|
||||
if context.scene.BCFProperties.is_loaded and not self.is_editable:
|
||||
bpy.ops.bim.edit_bcf_comment(comment_guid = self.name)
|
||||
bpy.ops.bim.edit_bcf_comment(comment_guid=self.name)
|
||||
|
||||
|
||||
def refreshBcfTopic(self, context):
|
||||
@@ -91,7 +90,7 @@ class BcfLabel(PropertyGroup):
|
||||
|
||||
def getBcfViewpoints(self, context, force_update=False):
|
||||
global bcfviewpoints_enum
|
||||
if bcfviewpoints_enum is None or force_update: # Retrieving Viewpoints is slow. Make sure we only do when needed
|
||||
if bcfviewpoints_enum is None or force_update: # Retrieving Viewpoints is slow. Make sure we only do when needed
|
||||
bcfviewpoints_enum = []
|
||||
props = context.scene.BCFProperties
|
||||
bcfxml = bcfstore.BcfStore.get_bcfxml()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -22,6 +21,7 @@ import bpy
|
||||
from . import bcfstore
|
||||
from bpy.types import Panel
|
||||
|
||||
|
||||
class BIM_PT_bcf(Panel):
|
||||
bl_label = "BCF Project"
|
||||
bl_idname = "BIM_PT_bcf"
|
||||
@@ -231,12 +231,12 @@ class BIM_PT_bcf_metadata(Panel):
|
||||
row.operator("bim.add_bcf_document_reference")
|
||||
|
||||
layout.label(text="Related Topics:")
|
||||
for index, related_topic in enumerate(topic.related_topics):
|
||||
for index, related_topic in enumerate(topic.related_topics):
|
||||
try:
|
||||
row = layout.row(align=True)
|
||||
op = row.operator(
|
||||
"bim.view_bcf_topic",
|
||||
text=f"Select {bcfxml.topics[related_topic.name.lower()].title}")
|
||||
"bim.view_bcf_topic", text=f"Select {bcfxml.topics[related_topic.name.lower()].title}"
|
||||
)
|
||||
op.topic_guid = related_topic.name
|
||||
row.operator("bim.remove_bcf_related_topic", icon="X", text="").index = index
|
||||
except KeyError:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -21,7 +20,6 @@ import os
|
||||
import bpy
|
||||
import tempfile
|
||||
import webbrowser
|
||||
import ifcopenshell
|
||||
|
||||
try:
|
||||
import bimtester
|
||||
@@ -31,7 +29,6 @@ except:
|
||||
print("Failed to load BIMTester. Try disabling other add-ons, in particular Blender-OSM. See bug #1318.")
|
||||
|
||||
from pathlib import Path
|
||||
from itertools import cycle
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
@@ -42,7 +39,7 @@ class ExecuteBIMTester(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.BimTesterProperties
|
||||
return props.ifc_file and props.feature
|
||||
return (props.ifc_file or props.should_load_from_memory) and props.feature
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BimTesterProperties
|
||||
@@ -75,10 +72,6 @@ class BIMTesterPurge(bpy.types.Operator):
|
||||
bl_label = "Purge Tests"
|
||||
|
||||
def execute(self, context):
|
||||
filename = os.path.join(
|
||||
context.scene.BimTesterProperties.features_dir,
|
||||
context.scene.BimTesterProperties.features_file + ".feature",
|
||||
)
|
||||
cwd = os.getcwd()
|
||||
os.chdir(context.scene.BimTesterProperties.features_dir)
|
||||
bimtester.clean.TestPurger().purge()
|
||||
@@ -243,19 +236,3 @@ class QAHelper:
|
||||
is_in_scenario = False
|
||||
destination.write(source_line)
|
||||
os.remove(filename + "~")
|
||||
|
||||
|
||||
colour_list = [
|
||||
(0.651, 0.81, 0.892, 1),
|
||||
(0.121, 0.471, 0.706, 1),
|
||||
(0.699, 0.876, 0.54, 1),
|
||||
(0.199, 0.629, 0.174, 1),
|
||||
(0.983, 0.605, 0.602, 1),
|
||||
(0.89, 0.101, 0.112, 1),
|
||||
(0.989, 0.751, 0.427, 1),
|
||||
(0.986, 0.497, 0.1, 1),
|
||||
(0.792, 0.699, 0.839, 1),
|
||||
(0.414, 0.239, 0.603, 1),
|
||||
(0.993, 0.999, 0.6, 1),
|
||||
(0.693, 0.349, 0.157, 1),
|
||||
]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -20,9 +19,7 @@
|
||||
import bpy
|
||||
from . import ui
|
||||
|
||||
classes = (
|
||||
ui.BIM_PT_boundary,
|
||||
)
|
||||
classes = (ui.BIM_PT_boundary,)
|
||||
|
||||
|
||||
def register():
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -232,9 +231,7 @@ class ExecuteIfcClash(bpy.types.Operator):
|
||||
context.scene.render.resolution_x = 480
|
||||
context.scene.render.resolution_y = 270
|
||||
context.scene.render.image_settings.file_format = "PNG"
|
||||
context.scene.render.filepath = os.path.join(
|
||||
context.scene.BIMProperties.data_dir, "snapshot.png"
|
||||
)
|
||||
context.scene.render.filepath = os.path.join(context.scene.BIMProperties.data_dir, "snapshot.png")
|
||||
bpy.ops.render.opengl(write_still=True)
|
||||
return context.scene.render.filepath
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -69,13 +68,14 @@ class ExecuteIfcCobie(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
from cobie import IfcCobieParser
|
||||
|
||||
props = context.scene.COBieProperties
|
||||
|
||||
if props.should_load_from_memory:
|
||||
output_dir = tempfile.gettempdir()
|
||||
else:
|
||||
output_dir = os.path.dirname(props.cobie_ifc_file)
|
||||
|
||||
output_dir = os.path.dirname(props.cobie_ifc_file)
|
||||
|
||||
output = os.path.join(output_dir, "output")
|
||||
logger = logging.getLogger("IFCtoCOBie")
|
||||
fh = logging.FileHandler(os.path.join(output_dir, "cobie.log"))
|
||||
@@ -92,10 +92,10 @@ class ExecuteIfcCobie(bpy.types.Operator):
|
||||
parser = IfcCobieParser(logger, selector)
|
||||
|
||||
ifc_file = IfcStore.get_file()
|
||||
|
||||
|
||||
if not (ifc_file and props.should_load_from_memory):
|
||||
ifc_file = props.cobie_ifc_file
|
||||
|
||||
|
||||
parser.parse(
|
||||
ifc_file,
|
||||
props.cobie_types,
|
||||
@@ -122,4 +122,3 @@ class ExecuteIfcCobie(bpy.types.Operator):
|
||||
webbrowser.open("file://" + output_dir)
|
||||
webbrowser.open("file://" + output_dir + "/cobie.log")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -37,4 +36,3 @@ class COBieProperties(PropertyGroup):
|
||||
cobie_components: StringProperty(default=".COBie", name="COBie Components")
|
||||
cobie_json_file: StringProperty(default="", name="COBie JSON File")
|
||||
should_load_from_memory: BoolProperty(default=False, name="Load from Memory")
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -36,11 +35,10 @@ class BIM_PT_cobie(Panel):
|
||||
scene = context.scene
|
||||
props = scene.COBieProperties
|
||||
|
||||
|
||||
if IfcStore.get_file():
|
||||
if IfcStore.get_file():
|
||||
row = layout.row()
|
||||
row.prop(props, "should_load_from_memory")
|
||||
|
||||
|
||||
if not IfcStore.get_file() or not props.should_load_from_memory:
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, "cobie_ifc_file")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -105,7 +104,7 @@ class BIM_PT_object_constraints(Panel):
|
||||
constraint = Data.objectives[constraint_id]
|
||||
icon = "LIGHT"
|
||||
except:
|
||||
pass # Metric not implemented
|
||||
pass # Metric not implemented
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=constraint.get("Name") or "Unnamed")
|
||||
row.operator("bim.unassign_constraint", text="", icon="X").constraint = constraint_id
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -463,6 +463,7 @@ class BIM_PT_cost_item_quantities(Panel):
|
||||
row2 = col.row()
|
||||
row2.prop(self.props, "resource_quantity_names", text="")
|
||||
|
||||
|
||||
class BIM_PT_cost_item_rates(Panel):
|
||||
bl_label = "IFC Cost Item Rates"
|
||||
bl_idname = "BIM_PT_cost_item_rates"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -32,11 +31,9 @@ classes = (
|
||||
)
|
||||
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.Scene.CsvProperties = bpy.props.PointerProperty(type=prop.CsvProperties)
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Scene.CsvProperties
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -18,6 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import time
|
||||
import logging
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.placement
|
||||
@@ -88,10 +88,7 @@ class ProfileImportIFC(bpy.types.Operator):
|
||||
import cProfile
|
||||
import pstats
|
||||
|
||||
# For Windows
|
||||
filepath = context.scene.BIMProperties.ifc_file.replace("\\", "\\\\")
|
||||
|
||||
cProfile.run(f"import bpy; bpy.ops.import_ifc.bim(filepath='{filepath}')", "blender.prof")
|
||||
cProfile.run("import bpy; bpy.ops.bim.load_project_elements()", "blender.prof")
|
||||
p = pstats.Stats("blender.prof")
|
||||
p.sort_stats("cumulative").print_stats(50)
|
||||
return {"FINISHED"}
|
||||
@@ -116,9 +113,10 @@ class CreateAllShapes(bpy.types.Operator):
|
||||
if element.GlobalId in excludes:
|
||||
continue
|
||||
print(f"{i}/{total}:", element)
|
||||
start = time.time()
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(settings, element)
|
||||
print("Success", len(shape.geometry.verts), len(shape.geometry.edges), len(shape.geometry.faces))
|
||||
print("Success", time.time()-start, len(shape.geometry.verts), len(shape.geometry.edges), len(shape.geometry.faces))
|
||||
except:
|
||||
failures.append(element)
|
||||
print("***** FAILURE *****")
|
||||
@@ -164,9 +162,11 @@ class SelectHighPolygonMeshes(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
[o.select_set(True) for o in context.view_layer.objects
|
||||
if o.type == "MESH"
|
||||
and len(o.data.polygons) > context.scene.BIMDebugProperties.number_of_polygons]
|
||||
[
|
||||
o.select_set(True)
|
||||
for o in context.view_layer.objects
|
||||
if o.type == "MESH" and len(o.data.polygons) > context.scene.BIMDebugProperties.number_of_polygons
|
||||
]
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -31,11 +30,9 @@ classes = (
|
||||
)
|
||||
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.Scene.DiffProperties = bpy.props.PointerProperty(type=prop.DiffProperties)
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Scene.DiffProperties
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -24,7 +23,6 @@ import json
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
|
||||
class SelectDiffJsonFile(bpy.types.Operator):
|
||||
bl_idname = "bim.select_diff_json_file"
|
||||
bl_label = "Select Diff JSON File"
|
||||
@@ -46,8 +44,8 @@ class VisualiseDiff(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
#ifc_file = IfcStore.get_file() # In case we get from Store
|
||||
ifc_file = ifcopenshell.open(context.scene.DiffProperties.diff_new_file) # for Now refer to the new file
|
||||
# ifc_file = IfcStore.get_file() # In case we get from Store
|
||||
ifc_file = ifcopenshell.open(context.scene.DiffProperties.diff_new_file) # for Now refer to the new file
|
||||
with open(context.scene.DiffProperties.diff_json_file, "r") as file:
|
||||
diff = json.load(file)
|
||||
for obj in context.visible_objects:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -171,16 +170,14 @@ class Annotator:
|
||||
camera = context.scene.camera
|
||||
z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
|
||||
if context.scene.render.resolution_x > context.scene.render.resolution_y:
|
||||
y = (
|
||||
camera.data.ortho_scale
|
||||
* (context.scene.render.resolution_y / context.scene.render.resolution_x)
|
||||
/ 4
|
||||
)
|
||||
y = camera.data.ortho_scale * (context.scene.render.resolution_y / context.scene.render.resolution_x) / 4
|
||||
else:
|
||||
y = camera.data.ortho_scale / 4
|
||||
y_offset = camera.matrix_world.to_quaternion() @ Vector((0, y, 0))
|
||||
x_offset = camera.matrix_world.to_quaternion() @ Vector((y/2, 0, 0))
|
||||
return (camera.location + z_offset,
|
||||
camera.location + z_offset + y_offset,
|
||||
camera.location + z_offset + x_offset,
|
||||
camera.location + z_offset + x_offset + y_offset)
|
||||
x_offset = camera.matrix_world.to_quaternion() @ Vector((y / 2, 0, 0))
|
||||
return (
|
||||
camera.location + z_offset,
|
||||
camera.location + z_offset + y_offset,
|
||||
camera.location + z_offset + x_offset,
|
||||
camera.location + z_offset + x_offset + y_offset,
|
||||
)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -35,7 +34,7 @@ from gpu_extras.batch import batch_for_shader
|
||||
import blenderbim.bim.module.drawing.helper as helper
|
||||
|
||||
|
||||
class BaseDecorator():
|
||||
class BaseDecorator:
|
||||
# base name of objects to decorate
|
||||
basename = "IfcAnnotation/Something"
|
||||
|
||||
@@ -128,10 +127,12 @@ class BaseDecorator():
|
||||
|
||||
def __init__(self):
|
||||
# NB: libcode param doesn't work
|
||||
self.shader = GPUShader(vertexcode=self.VERT_GLSL,
|
||||
fragcode=self.FRAG_GLSL,
|
||||
geocode=self.LIB_GLSL + self.GEOM_GLSL,
|
||||
defines=self.DEF_GLSL)
|
||||
self.shader = GPUShader(
|
||||
vertexcode=self.VERT_GLSL,
|
||||
fragcode=self.FRAG_GLSL,
|
||||
geocode=self.LIB_GLSL + self.GEOM_GLSL,
|
||||
defines=self.DEF_GLSL,
|
||||
)
|
||||
|
||||
def get_objects(self, collection):
|
||||
"""find relevant objects
|
||||
@@ -172,7 +173,7 @@ class BaseDecorator():
|
||||
topology.append(1)
|
||||
topology.extend([0] * max(0, cnt - 2))
|
||||
topology.append(2)
|
||||
indices.extend((idx+i, idx+i+1) for i in range(cnt-1))
|
||||
indices.extend((idx + i, idx + i + 1) for i in range(cnt - 1))
|
||||
idx += cnt
|
||||
|
||||
return vertices, indices, topology
|
||||
@@ -192,8 +193,7 @@ class BaseDecorator():
|
||||
return vertices, indices
|
||||
|
||||
def get_editmesh_geom(self, obj):
|
||||
"""Parses editmode mesh geometry into line segments
|
||||
"""
|
||||
"""Parses editmode mesh geometry into line segments"""
|
||||
mesh = bmesh.from_edit_mesh(obj.data)
|
||||
vertices = []
|
||||
indices = []
|
||||
@@ -201,7 +201,7 @@ class BaseDecorator():
|
||||
|
||||
for edge in mesh.edges:
|
||||
vertices.extend(edge.verts)
|
||||
indices.append((idx, idx+1))
|
||||
indices.append((idx, idx + 1))
|
||||
idx += 2
|
||||
vertices = [obj.matrix_world @ v.co for v in vertices]
|
||||
|
||||
@@ -217,18 +217,18 @@ class BaseDecorator():
|
||||
color = context.scene.DocProperties.decorations_colour
|
||||
|
||||
fmt = GPUVertFormat()
|
||||
fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT')
|
||||
fmt.attr_add(id="pos", comp_type="F32", len=3, fetch_mode="FLOAT")
|
||||
if topology:
|
||||
fmt.attr_add(id="topo", comp_type='U8', len=1, fetch_mode='INT')
|
||||
fmt.attr_add(id="topo", comp_type="U8", len=1, fetch_mode="INT")
|
||||
|
||||
vbo = GPUVertBuf(len=len(vertices), format=fmt)
|
||||
vbo.attr_fill(id="pos", data=vertices)
|
||||
if topology:
|
||||
vbo.attr_fill(id="topo", data=topology)
|
||||
|
||||
ibo = GPUIndexBuf(type='LINES', seq=indices)
|
||||
ibo = GPUIndexBuf(type="LINES", seq=indices)
|
||||
|
||||
batch = GPUBatch(type='LINES', buf=vbo, elem=ibo)
|
||||
batch = GPUBatch(type="LINES", buf=vbo, elem=ibo)
|
||||
|
||||
bgl.glEnable(bgl.GL_LINE_SMOOTH)
|
||||
bgl.glHint(bgl.GL_LINE_SMOOTH_HINT, bgl.GL_NICEST)
|
||||
@@ -289,7 +289,7 @@ class BaseDecorator():
|
||||
|
||||
def format_value(self, context, value):
|
||||
unit_system = context.scene.unit_settings.system
|
||||
if unit_system == 'IMPERIAL':
|
||||
if unit_system == "IMPERIAL":
|
||||
precision = context.scene.BIMProperties.imperial_precision
|
||||
if precision == "NONE":
|
||||
precision = 256
|
||||
@@ -297,12 +297,12 @@ class BaseDecorator():
|
||||
precision = 1
|
||||
elif "/" in precision:
|
||||
precision = int(precision.split("/")[1])
|
||||
elif unit_system == 'METRIC':
|
||||
elif unit_system == "METRIC":
|
||||
precision = 3
|
||||
else:
|
||||
return
|
||||
|
||||
return bpy.utils.units.to_string(unit_system, 'LENGTH', value, precision, split_unit=True)
|
||||
return bpy.utils.units.to_string(unit_system, "LENGTH", value, precision, split_unit=True)
|
||||
|
||||
|
||||
class DimensionDecorator(BaseDecorator):
|
||||
@@ -310,12 +310,16 @@ class DimensionDecorator(BaseDecorator):
|
||||
- each edge of a segment with arrow
|
||||
- puts metric text next to each segment
|
||||
"""
|
||||
|
||||
basename = "IfcAnnotation/Dimension"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define ARROW_ANGLE PI / 12.0
|
||||
#define ARROW_SIZE 16.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -392,7 +396,7 @@ class DimensionDecorator(BaseDecorator):
|
||||
continue
|
||||
length = (v1 - v0).length
|
||||
text = self.format_value(context, length)
|
||||
self.draw_label(context, text, p0 + (dir) * .5, dir)
|
||||
self.draw_label(context, text, p0 + (dir) * 0.5, dir)
|
||||
|
||||
|
||||
class EqualityDecorator(DimensionDecorator):
|
||||
@@ -401,6 +405,7 @@ class EqualityDecorator(DimensionDecorator):
|
||||
- augments with arrows on both sides
|
||||
- puts 'EQ' label
|
||||
"""
|
||||
|
||||
basename = "IfcAnnotation/Equal"
|
||||
|
||||
def draw_labels(self, context, obj, vertices, indices):
|
||||
@@ -414,7 +419,7 @@ class EqualityDecorator(DimensionDecorator):
|
||||
dir = p1 - p0
|
||||
if dir.length < 1:
|
||||
continue
|
||||
self.draw_label(context, "EQ", p0 + (dir) * .5, dir)
|
||||
self.draw_label(context, "EQ", p0 + (dir) * 0.5, dir)
|
||||
|
||||
|
||||
class LeaderDecorator(BaseDecorator):
|
||||
@@ -422,12 +427,16 @@ class LeaderDecorator(BaseDecorator):
|
||||
- head point with arrow
|
||||
- middle points w/out decorations
|
||||
"""
|
||||
|
||||
basename = "IfcAnnotation/Leader"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define ARROW_ANGLE PI / 12.0
|
||||
#define ARROW_SIZE 16.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -490,13 +499,17 @@ class StairDecorator(BaseDecorator):
|
||||
- tail point with circle
|
||||
- middle points w/out decorations
|
||||
"""
|
||||
|
||||
basename = "IfcAnnotation/Stair"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define CIRCLE_SIZE 8.0
|
||||
#define ARROW_ANGLE PI / 3.0
|
||||
#define ARROW_SIZE 24.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -572,10 +585,13 @@ class StairDecorator(BaseDecorator):
|
||||
class HiddenDecorator(BaseDecorator):
|
||||
basename = "IfcAnnotation/Hidden"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define DASH_SIZE 16.0
|
||||
#define DASH_PATTERN 0x0000FFFFU
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -639,7 +655,6 @@ class MiscDecorator(HiddenDecorator):
|
||||
|
||||
|
||||
class LevelDecorator(BaseDecorator):
|
||||
|
||||
def get_splines(self, obj):
|
||||
"""Iterates through splines
|
||||
Args:
|
||||
@@ -664,10 +679,13 @@ class LevelDecorator(BaseDecorator):
|
||||
class PlanLevelDecorator(LevelDecorator):
|
||||
basename = "IfcAnnotation/Plan Level"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define CIRCLE_SIZE 8.0
|
||||
#define CROSS_SIZE 16.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -746,10 +764,13 @@ class PlanLevelDecorator(LevelDecorator):
|
||||
class SectionLevelDecorator(LevelDecorator):
|
||||
basename = "IfcAnnotation/Section Level"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define CALLOUT_GAP 8.0
|
||||
#define CALLOUT_SIZE 64.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -828,12 +849,16 @@ class BreakDecorator(BaseDecorator):
|
||||
|
||||
Uses first two vertices in verts list.
|
||||
"""
|
||||
|
||||
basename = "IfcAnnotation/Break"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define BREAK_LENGTH 32.0
|
||||
#define BREAK_WIDTH 16.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -905,11 +930,14 @@ class BreakDecorator(BaseDecorator):
|
||||
class GridDecorator(BaseDecorator):
|
||||
basename = "IfcGridAxis/"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define CIRCLE_SIZE 16.0
|
||||
#define DASH_SIZE 48.0
|
||||
#define DASH_PATTERN 0x03C0FFFFU
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -1019,11 +1047,14 @@ class GridDecorator(BaseDecorator):
|
||||
class SectionViewDecorator(LevelDecorator):
|
||||
basename = "IfcAnnotation/Section"
|
||||
|
||||
DEF_GLSL = BaseDecorator.DEF_GLSL + """
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define CIRCLE_SIZE 8.0
|
||||
#define TRIANGLE_L 32.0
|
||||
#define TRIANGLE_W 16.0
|
||||
"""
|
||||
)
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
@@ -1118,7 +1149,7 @@ class SectionViewDecorator(LevelDecorator):
|
||||
self.draw_lines(context, obj, verts, [(0, 1)])
|
||||
|
||||
|
||||
class DecorationsHandler():
|
||||
class DecorationsHandler:
|
||||
decorators_classes = [
|
||||
DimensionDecorator,
|
||||
EqualityDecorator,
|
||||
@@ -1130,7 +1161,7 @@ class DecorationsHandler():
|
||||
SectionLevelDecorator,
|
||||
StairDecorator,
|
||||
BreakDecorator,
|
||||
SectionViewDecorator
|
||||
SectionViewDecorator,
|
||||
]
|
||||
|
||||
installed = None
|
||||
@@ -1140,12 +1171,12 @@ class DecorationsHandler():
|
||||
if cls.installed:
|
||||
cls.uninstall()
|
||||
handler = cls()
|
||||
cls.installed = SpaceView3D.draw_handler_add(handler, (context,), 'WINDOW', 'POST_PIXEL')
|
||||
cls.installed = SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_PIXEL")
|
||||
|
||||
@classmethod
|
||||
def uninstall(cls):
|
||||
try:
|
||||
SpaceView3D.draw_handler_remove(cls.installed, 'WINDOW')
|
||||
SpaceView3D.draw_handler_remove(cls.installed, "WINDOW")
|
||||
except ValueError:
|
||||
pass
|
||||
cls.installed = None
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -26,6 +25,7 @@ from mathutils import Vector, Matrix
|
||||
from mathutils import geometry
|
||||
from bpy_extras import view3d_utils
|
||||
from blenderbim.bim.module.drawing.shaders import DotsGizmoShader, ExtrusionGuidesShader, BaseLinesShader
|
||||
from ifcopenshell.util.unit import si_conversions
|
||||
|
||||
|
||||
"""Gizmos under the hood
|
||||
@@ -470,8 +470,6 @@ class ExtrusionWidget(types.GizmoGroup):
|
||||
bl_region_type = "WINDOW"
|
||||
bl_options = {"3D", "PERSISTENT", "SHOW_MODAL_ALL"}
|
||||
|
||||
# FIXME: use proper scale from ifc value to blender units
|
||||
|
||||
@classmethod
|
||||
def poll(cls, ctx):
|
||||
obj = ctx.object
|
||||
@@ -487,6 +485,7 @@ class ExtrusionWidget(types.GizmoGroup):
|
||||
|
||||
basis = target.matrix_world.normalized()
|
||||
theme = ctx.preferences.themes[0].user_interface
|
||||
scale_value = self.get_scale_value(ctx.scene.unit_settings.system, ctx.scene.unit_settings.length_unit)
|
||||
|
||||
gz = self.handle = self.gizmos.new("BIM_GT_uglydot_3d")
|
||||
gz.matrix_basis = basis
|
||||
@@ -496,7 +495,7 @@ class ExtrusionWidget(types.GizmoGroup):
|
||||
gz.alpha_highlight = 1.0
|
||||
gz.use_draw_modal = True
|
||||
gz.target_set_prop("offset", prop, "value")
|
||||
gz.scale_value = 1000
|
||||
gz.scale_value = scale_value
|
||||
|
||||
gz = self.guides = self.gizmos.new("BIM_GT_extrusion_guides")
|
||||
gz.matrix_basis = basis
|
||||
@@ -504,7 +503,7 @@ class ExtrusionWidget(types.GizmoGroup):
|
||||
gz.alpha = gz.alpha_highlight = 0.5
|
||||
gz.use_draw_modal = True
|
||||
gz.target_set_prop("depth", prop, "value")
|
||||
gz.scale_value = 1000
|
||||
gz.scale_value = scale_value
|
||||
|
||||
# gz = self.label = self.gizmos.new('GIZMO_GT_dimension_label')
|
||||
# gz.matrix_basis = basis
|
||||
@@ -523,10 +522,30 @@ class ExtrusionWidget(types.GizmoGroup):
|
||||
def update(self, ctx):
|
||||
"""updating object"""
|
||||
bpy.ops.bim.update_parametric_representation()
|
||||
# parameters disappear after update
|
||||
# need to retrieve and rebind them again
|
||||
bpy.ops.bim.get_representation_ifc_parameters()
|
||||
target = ctx.object
|
||||
prop = target.data.BIMMeshProperties.ifc_parameters.get("IfcExtrudedAreaSolid/Depth")
|
||||
self.handle.target_set_prop("offset", prop, "value")
|
||||
self.guides.target_set_prop("depth", prop, "value")
|
||||
|
||||
@staticmethod
|
||||
def get_scale_value(system, length_unit):
|
||||
scale_value = 1
|
||||
if system == "METRIC":
|
||||
if length_unit == "KILOMETERS":
|
||||
scale_value /= 1000
|
||||
elif length_unit == "CENTIMETERS":
|
||||
scale_value *= 100
|
||||
elif length_unit == "MILLIMETERS":
|
||||
scale_value *= 1000
|
||||
elif length_unit == "MICROMETERS":
|
||||
scale_value *= 1000000
|
||||
elif system == "IMPERIAL":
|
||||
if length_unit == "MILES":
|
||||
scale_value /= si_conversions["mile"]
|
||||
elif length_unit == "FEET":
|
||||
scale_value /= si_conversions["foot"]
|
||||
elif length_unit == "INCHES":
|
||||
scale_value /= si_conversions["inch"]
|
||||
elif length_unit == "THOU":
|
||||
scale_value /= si_conversions["thou"]
|
||||
return scale_value
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -125,15 +124,19 @@ class CreateDrawing(bpy.types.Operator):
|
||||
- IFC file is created
|
||||
- Camera is in Orthographic mode
|
||||
"""
|
||||
|
||||
bl_idname = "bim.create_drawing"
|
||||
bl_label = "Create Drawing"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
camera = context.scene.camera
|
||||
return IfcStore.get_file() \
|
||||
and camera.type == "CAMERA" and camera.data.type == "ORTHO" \
|
||||
return (
|
||||
IfcStore.get_file()
|
||||
and camera.type == "CAMERA"
|
||||
and camera.data.type == "ORTHO"
|
||||
and camera.BIMObjectProperties.ifc_definition_id
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
self.camera = context.scene.camera
|
||||
@@ -568,9 +571,7 @@ class OpenSheet(bpy.types.Operator):
|
||||
props = context.scene.DocProperties
|
||||
open_with_user_command(
|
||||
context.preferences.addons["blenderbim"].preferences.svg_command,
|
||||
os.path.join(
|
||||
context.scene.BIMProperties.data_dir, "sheets", props.active_sheet.name + ".svg"
|
||||
),
|
||||
os.path.join(context.scene.BIMProperties.data_dir, "sheets", props.active_sheet.name + ".svg"),
|
||||
)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -581,16 +582,16 @@ class AddDrawingToSheet(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
# TODO: check undo redo
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
return props.drawings and props.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.DocProperties
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.data_dir = context.scene.BIMProperties.data_dir
|
||||
try:
|
||||
sheet_builder.add_drawing(
|
||||
props.drawings.active_drawing.name, props.active_sheet.name
|
||||
)
|
||||
except FileNotFoundError:
|
||||
self.report({"ERROR"}, "Drawings need to be created before being added to a sheet")
|
||||
sheet_builder.add_drawing(props.active_drawing.name, props.active_sheet.name)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -599,6 +600,10 @@ class CreateSheets(bpy.types.Operator):
|
||||
bl_label = "Create Sheets"
|
||||
# TODO: check undo redo
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.DocProperties.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
props = scene.DocProperties
|
||||
@@ -657,6 +662,7 @@ class OpenView(bpy.types.Operator):
|
||||
|
||||
class OpenViewCamera(bpy.types.Operator):
|
||||
"""Select this drawing's camera object and expand its drawing properties"""
|
||||
|
||||
bl_idname = "bim.open_view_camera"
|
||||
bl_label = "Open View Camera"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
@@ -664,7 +670,7 @@ class OpenViewCamera(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return bpy.context.object.mode == "OBJECT"
|
||||
return context.mode == "OBJECT"
|
||||
|
||||
def execute(self, context):
|
||||
doc_props = context.scene.DocProperties
|
||||
@@ -943,9 +949,7 @@ class ActivateDrawingStyle(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
if scene.camera.data.BIMCameraProperties.active_drawing_style_index < len(
|
||||
scene.DocProperties.drawing_styles
|
||||
):
|
||||
if scene.camera.data.BIMCameraProperties.active_drawing_style_index < len(scene.DocProperties.drawing_styles):
|
||||
self.drawing_style = scene.DocProperties.drawing_styles[
|
||||
scene.camera.data.BIMCameraProperties.active_drawing_style_index
|
||||
]
|
||||
@@ -1103,13 +1107,16 @@ class AddScheduleToSheet(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
# TODO: check undo redo
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.DocProperties
|
||||
return props.schedules and props.sheets and context.scene.BIMProperties.data_dir
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.DocProperties
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.data_dir = context.scene.BIMProperties.data_dir
|
||||
sheet_builder.add_schedule(
|
||||
props.active_schedule.name, props.active_sheet.name
|
||||
)
|
||||
sheet_builder.add_schedule(props.active_schedule.name, props.active_sheet.name)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -1258,7 +1265,7 @@ class AddSectionsAnnotations(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
def poll(cls, context):
|
||||
camera = helper.get_active_drawing(context.scene)[1]
|
||||
return camera and camera.data.type == "ORTHO"
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -54,7 +53,7 @@ def purge():
|
||||
vector_styles_enum = []
|
||||
|
||||
|
||||
def getDiagramScales(self, context):
|
||||
def get_diagram_scales(self, context):
|
||||
global diagram_scales_enum
|
||||
if (
|
||||
len(diagram_scales_enum) < 1
|
||||
@@ -271,16 +270,17 @@ class DocProperties(PropertyGroup):
|
||||
|
||||
@property
|
||||
def active_schedule(self):
|
||||
return self.schedules[self.active_schedule_index]
|
||||
|
||||
return self.schedules[self.active_schedule_index]
|
||||
|
||||
@property
|
||||
def active_drawing(self):
|
||||
return self.drawings[self.active_drawing_index]
|
||||
|
||||
return self.drawings[self.active_drawing_index]
|
||||
|
||||
@property
|
||||
def active_sheet(self):
|
||||
return self.sheets[self.active_sheet_index]
|
||||
|
||||
|
||||
class BIMCameraProperties(PropertyGroup):
|
||||
view_name: StringProperty(name="View Name")
|
||||
target_view: EnumProperty(
|
||||
@@ -294,7 +294,7 @@ class BIMCameraProperties(PropertyGroup):
|
||||
name="Target View",
|
||||
default="PLAN_VIEW",
|
||||
)
|
||||
diagram_scale: EnumProperty(items=getDiagramScales, name="Drawing Scale")
|
||||
diagram_scale: EnumProperty(items=get_diagram_scales, name="Drawing Scale")
|
||||
custom_diagram_scale: StringProperty(name="Custom Scale")
|
||||
raster_x: IntProperty(name="Raster X", default=1000)
|
||||
raster_y: IntProperty(name="Raster Y", default=1000)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -27,7 +26,11 @@ from odf.style import Style
|
||||
|
||||
class Scheduler:
|
||||
def schedule(self, infile, outfile):
|
||||
self.svg = svgwrite.Drawing(outfile, debug=False, id="root",)
|
||||
self.svg = svgwrite.Drawing(
|
||||
outfile,
|
||||
debug=False,
|
||||
id="root",
|
||||
)
|
||||
self.padding = 1
|
||||
self.margin = 1
|
||||
doc = load(infile)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
# Copyright (C) 2020, 2021 Maxim Vasilyev <qwiglydee@gmail.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
@@ -24,7 +23,7 @@ from gpu_extras.batch import batch_for_shader
|
||||
|
||||
|
||||
class BaseShader:
|
||||
"""Wrapepr for GPUShader
|
||||
"""Wrapper for GPUShader
|
||||
To use for viewport decorations with geometry generated on GPU side.
|
||||
|
||||
The Geometry shader works in clipping coords (aftre projecting before division and window scaling).
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -45,7 +44,7 @@ class External(svgwrite.container.Group):
|
||||
self.xml = xml
|
||||
|
||||
# Remove namespace
|
||||
ns = u"{http://www.w3.org/2000/svg}"
|
||||
ns = "{http://www.w3.org/2000/svg}"
|
||||
nsl = len(ns)
|
||||
for elem in self.xml.iter():
|
||||
if elem.tag.startswith(ns):
|
||||
@@ -123,12 +122,12 @@ class SvgWriter:
|
||||
self.svg.add(
|
||||
self.svg.image(
|
||||
os.path.join("..", "diagrams", os.path.basename(self.background_image)),
|
||||
**{"width": self.width, "height": self.height}
|
||||
**{"width": self.width, "height": self.height},
|
||||
)
|
||||
)
|
||||
|
||||
def draw_background_elements(self):
|
||||
return # TODO purge?
|
||||
return # TODO purge?
|
||||
for element in self.ifc_cutter.background_elements:
|
||||
if element["type"] == "polygon":
|
||||
self.draw_polygon(element, "background")
|
||||
@@ -180,7 +179,7 @@ class SvgWriter:
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
"dominant-baseline": "middle",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
self.svg.add(
|
||||
@@ -193,7 +192,7 @@ class SvgWriter:
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
"dominant-baseline": "middle",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -252,7 +251,7 @@ class SvgWriter:
|
||||
"text-anchor": text_anchor,
|
||||
"alignment-baseline": "baseline",
|
||||
"dominant-baseline": "baseline",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -294,7 +293,7 @@ class SvgWriter:
|
||||
"text-anchor": "start",
|
||||
"alignment-baseline": "baseline",
|
||||
"dominant-baseline": "baseline",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -325,7 +324,7 @@ class SvgWriter:
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
"dominant-baseline": "middle",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
self.draw_text_annotations()
|
||||
@@ -473,7 +472,9 @@ class SvgWriter:
|
||||
)
|
||||
|
||||
transform = "rotate({}, {}, {})".format(
|
||||
angle, (text_position * self.scale)[0], (text_position * self.scale)[1],
|
||||
angle,
|
||||
(text_position * self.scale)[0],
|
||||
(text_position * self.scale)[1],
|
||||
)
|
||||
|
||||
if text_obj.data.BIMTextProperties.symbol != "None":
|
||||
@@ -516,7 +517,7 @@ class SvgWriter:
|
||||
"alignment-baseline": alignment_baseline,
|
||||
"dominant-baseline": alignment_baseline,
|
||||
"transform": transform,
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -607,7 +608,7 @@ class SvgWriter:
|
||||
"font-size": annotation.Annotator.get_svg_text_size(2.5),
|
||||
"font-family": "OpenGost Type B TT",
|
||||
"text-anchor": "middle",
|
||||
}
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -623,7 +624,7 @@ class SvgWriter:
|
||||
return spline.bezier_points if spline.bezier_points else spline.points
|
||||
|
||||
def draw_cut_polygons(self):
|
||||
return # deprecate?
|
||||
return # deprecate?
|
||||
for polygon in self.ifc_cutter.cut_polygons:
|
||||
self.draw_polygon(polygon, "cut")
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -17,10 +16,8 @@
|
||||
# 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 os
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
from bpy.props import StringProperty, BoolProperty
|
||||
|
||||
|
||||
class BIM_PT_camera(Panel):
|
||||
@@ -32,7 +29,6 @@ class BIM_PT_camera(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
engine = context.engine
|
||||
return context.camera and hasattr(context.active_object.data, "BIMCameraProperties")
|
||||
|
||||
def draw(self, context):
|
||||
@@ -105,7 +101,6 @@ class BIM_PT_drawing_underlay(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
engine = context.engine
|
||||
return context.camera and hasattr(context.active_object.data, "BIMCameraProperties")
|
||||
|
||||
def draw(self, context):
|
||||
@@ -150,7 +145,6 @@ class BIM_PT_drawing_underlay(Panel):
|
||||
row.operator("bim.activate_drawing_style")
|
||||
|
||||
|
||||
|
||||
class BIM_PT_drawings(Panel):
|
||||
bl_label = "SVG Drawings"
|
||||
bl_idname = "BIM_PT_drawings"
|
||||
@@ -289,8 +283,6 @@ class BIM_PT_annotation_utilities(Panel):
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.clean_wireframes")
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.link_ifc")
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.add_grid")
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.add_sections_annotations")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -154,12 +153,11 @@ class AddRepresentation(bpy.types.Operator):
|
||||
"geometry.assign_representation", self.file, **{"product": product, "representation": result}
|
||||
)
|
||||
|
||||
existing_mesh = obj.data
|
||||
mesh = obj.data.copy()
|
||||
mesh.name = "{}/{}".format(context_id, result.id())
|
||||
mesh.BIMMeshProperties.ifc_definition_id = int(result.id())
|
||||
obj.data = mesh
|
||||
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
||||
Data.load(self.file, obj.BIMObjectProperties.ifc_definition_id)
|
||||
|
||||
if product.is_a("IfcTypeProduct"):
|
||||
if self.file.schema == "IFC2X3":
|
||||
@@ -168,7 +166,7 @@ class AddRepresentation(bpy.types.Operator):
|
||||
types = product.Types
|
||||
if types:
|
||||
for element in types[0].RelatedObjects:
|
||||
Data.load(IfcStore.get_file(), element.id())
|
||||
Data.load(self.file, element.id())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -239,7 +237,7 @@ class SwitchRepresentation(bpy.types.Operator):
|
||||
|
||||
if self.disable_opening_subtractions and self.context_of_items.ContextIdentifier == "Body":
|
||||
if self.oprops.ifc_definition_id not in VoidData.products:
|
||||
VoidData.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
|
||||
VoidData.load(self.file, self.oprops.ifc_definition_id)
|
||||
for opening_id in VoidData.products[self.oprops.ifc_definition_id]:
|
||||
opening = IfcStore.get_element(opening_id)
|
||||
if not opening:
|
||||
@@ -291,7 +289,7 @@ class RemoveRepresentation(bpy.types.Operator):
|
||||
"geometry.unassign_representation", self.file, **{"product": product, "representation": representation}
|
||||
)
|
||||
ifcopenshell.api.run("geometry.remove_representation", self.file, **{"representation": representation})
|
||||
Data.load(IfcStore.get_file(), product.id())
|
||||
Data.load(self.file, product.id())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -302,6 +300,10 @@ class UpdateRepresentation(bpy.types.Operator):
|
||||
obj: bpy.props.StringProperty()
|
||||
ifc_representation_class: bpy.props.StringProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object.mode == "OBJECT"
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
@@ -381,7 +383,9 @@ class UpdateRepresentation(bpy.types.Operator):
|
||||
obj.data.BIMMeshProperties.ifc_definition_id = int(new_representation.id())
|
||||
obj.data.name = f"{old_representation.ContextOfItems.id()}/{new_representation.id()}"
|
||||
bpy.ops.bim.remove_representation(representation_id=old_representation.id(), obj=obj.name)
|
||||
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
|
||||
Data.load(self.file, obj.BIMObjectProperties.ifc_definition_id)
|
||||
if obj.data.BIMMeshProperties.ifc_parameters:
|
||||
bpy.ops.bim.get_representation_ifc_parameters()
|
||||
|
||||
|
||||
class UpdateParametricRepresentation(bpy.types.Operator):
|
||||
@@ -390,15 +394,22 @@ class UpdateParametricRepresentation(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object.mode == "OBJECT"
|
||||
|
||||
def execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
obj = context.active_object
|
||||
props = obj.data.BIMMeshProperties
|
||||
parameter = props.ifc_parameters[self.index]
|
||||
element = IfcStore.get_file().by_id(parameter.step_id)[parameter.index] = parameter.value
|
||||
self.file.by_id(parameter.step_id)[parameter.index] = parameter.value
|
||||
show_representation_parameters = bool(props.ifc_parameters)
|
||||
bpy.ops.bim.switch_representation(
|
||||
ifc_definition_id=props.ifc_definition_id, should_reload=True, should_switch_all_meshes=True
|
||||
)
|
||||
if show_representation_parameters:
|
||||
bpy.ops.bim.get_representation_ifc_parameters()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -411,7 +422,8 @@ class GetRepresentationIfcParameters(bpy.types.Operator):
|
||||
self.file = IfcStore.get_file()
|
||||
obj = context.active_object
|
||||
props = obj.data.BIMMeshProperties
|
||||
elements = IfcStore.get_file().traverse(IfcStore.get_file().by_id(props.ifc_definition_id))
|
||||
elements = self.file.traverse(self.file.by_id(props.ifc_definition_id))
|
||||
props.ifc_parameters.clear()
|
||||
for element in elements:
|
||||
if element.is_a("IfcRepresentationItem") or element.is_a("IfcParameterizedProfileDef"):
|
||||
for i in range(0, len(element)):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -91,12 +90,12 @@ class BIM_PT_mesh(Panel):
|
||||
|
||||
row = layout.row(align=True)
|
||||
op = row.operator("bim.switch_representation", text="Bake Voids", icon="SELECT_SUBTRACT")
|
||||
op.should_switch_all_meshes=True
|
||||
op.should_switch_all_meshes = True
|
||||
op.should_reload = True
|
||||
op.ifc_definition_id = props.ifc_definition_id
|
||||
op.disable_opening_subtractions = False
|
||||
op = row.operator("bim.switch_representation", text="Dynamic Voids", icon="SELECT_INTERSECT")
|
||||
op.should_switch_all_meshes=True
|
||||
op.should_switch_all_meshes = True
|
||||
op.should_reload = True
|
||||
op.ifc_definition_id = props.ifc_definition_id
|
||||
op.disable_opening_subtractions = True
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
@@ -36,8 +35,8 @@ class BIMGeoreferenceProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
map_conversion: CollectionProperty(name="Map Conversion", type=Attribute)
|
||||
projected_crs: CollectionProperty(name="Projected CRS", type=Attribute)
|
||||
coordinate_input: StringProperty(name="Coordinate Input", description="Formatted \"x,y,z\" (without quotes)")
|
||||
coordinate_output: StringProperty(name="Coordinate Output", description="Formatted \"x,y,z\" (without quotes)")
|
||||
coordinate_input: StringProperty(name="Coordinate Input", description='Formatted "x,y,z" (without quotes)')
|
||||
coordinate_output: StringProperty(name="Coordinate Output", description='Formatted "x,y,z" (without quotes)')
|
||||
has_blender_offset: BoolProperty(name="Has Blender Offset")
|
||||
blender_eastings: StringProperty(name="Blender Eastings", default="0")
|
||||
blender_northings: StringProperty(name="Blender Northings", default="0")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user