mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 21:53:40 +00:00
Merge remote-tracking branch 'origin/v0.8.0' into datamodel-v1.0
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# Build Bonsai .zip.
|
||||
# Usage:
|
||||
# # While in `bonsai` folder.
|
||||
# docker build -t bonsai-dist .
|
||||
# # Output zip file will be in `dist` folder.
|
||||
# # See possible values for variables in `Makefile`'s `dist` target description.
|
||||
# docker run --rm -v "$PWD/../../:/work" -w /work -e PLATFORM=win -e PYVERSION=py313 bonsai-dist
|
||||
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y make git wget unzip zip
|
||||
|
||||
# Python
|
||||
RUN apt-get install -y software-properties-common
|
||||
RUN add-apt-repository ppa:deadsnakes/ppa
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y python3.11 python3.11-venv
|
||||
|
||||
RUN apt-get install -y npm
|
||||
|
||||
WORKDIR /work
|
||||
CMD cd src/bonsai && make dist PLATFORM=$PLATFORM PYVERSION=$PYVERSION
|
||||
+50
-48
@@ -48,18 +48,35 @@ VERSION_PATCH:=$(shell cat '../../VERSION' | cut -d '.' -f 3)
|
||||
VERSION_DATE:=$(shell date '+%y%m%d')
|
||||
LAST_COMMIT_HASH:=$(shell git rev-parse HEAD)
|
||||
LAST_COMMIT_DATE:=$(shell git show -s --format=%cI)
|
||||
PYVERSION:=py310
|
||||
LAST_GIT_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
|
||||
PYPI_IMP:=cp
|
||||
|
||||
ifeq ($(PYVERSION), py311)
|
||||
PYLIBDIR:=python3.11
|
||||
PYNUMBER:=311
|
||||
PYPI_VERSION:=3.11
|
||||
ifdef PYVERSION
|
||||
SUPPORTED_PYVERSIONS := py311 py312 py313
|
||||
|
||||
ifeq ($(filter $(PYVERSION),$(SUPPORTED_PYVERSIONS)),)
|
||||
$(error Unsupported PYVERSION=$(PYVERSION). Must be one of $(SUPPORTED_PYVERSIONS))
|
||||
endif
|
||||
|
||||
PYMINOR:=$(subst py3,,$(PYVERSION))
|
||||
PYLIBDIR:=python3.$(PYMINOR)
|
||||
PYNUMBER:=3$(PYMINOR)
|
||||
PYPI_VERSION:=3.$(PYMINOR)
|
||||
endif # def PYVERSION
|
||||
|
||||
IFCMERGE_VERSION:=2026-04-07
|
||||
|
||||
ifdef PLATFORM
|
||||
SUPPORTED_PLATFORMS := linux macos macosm1 win
|
||||
|
||||
ifeq ($(filter $(PLATFORM),$(SUPPORTED_PLATFORMS)),)
|
||||
$(error Unsupported PLATFORM=$(PLATFORM). Must be one of $(SUPPORTED_PLATFORMS))
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),macos)
|
||||
ifeq ($(PYVERSION),py313)
|
||||
$(error Blender 5.1 with Python 3.13 doesn't support intel macOS.)
|
||||
endif
|
||||
ifeq ($(PYVERSION), py312)
|
||||
PYLIBDIR:=python3.12
|
||||
PYNUMBER:=312
|
||||
PYPI_VERSION:=3.12
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), linux)
|
||||
@@ -86,8 +103,10 @@ PYPI_PLATFORM:=--platform win_amd64
|
||||
BLENDER_PLATFORM:=windows-x64
|
||||
endif
|
||||
|
||||
endif # def PLATFORM
|
||||
|
||||
# Current build commit hash.
|
||||
OLD:=e8eb5e4
|
||||
OLD:=1c5b825
|
||||
.PHONY: bump
|
||||
bump:
|
||||
ifndef NEW
|
||||
@@ -99,7 +118,10 @@ endif
|
||||
.PHONY: dist
|
||||
dist:
|
||||
ifndef PLATFORM
|
||||
$(error PLATFORM is not set)
|
||||
$(error PLATFORM is not set. Example values: $(SUPPORTED_PLATFORMS).)
|
||||
endif
|
||||
ifndef PYVERSION
|
||||
$(error PYVERSION is not set. Example values: $(SUPPORTED_PYVERSIONS). )
|
||||
endif
|
||||
rm -rf build
|
||||
mkdir -p build
|
||||
@@ -125,9 +147,6 @@ endif
|
||||
cd ../ifc5d && make dist && mv dist/*.whl ../bonsai/build/wheels/
|
||||
cd ../ifccityjson && make dist && mv dist/*.whl ../bonsai/build/wheels/
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download GitPython --dest=./wheels
|
||||
# Provides audio playback for costing
|
||||
# This is a REALLY IMPORTANT feature
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) wheel git+https://github.com/zdhoward/aud --wheel-dir=./wheels
|
||||
# IfcOpenShell dependency - support for new typing features
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download typing_extensions --dest=./wheels
|
||||
# Required by IfcCSV
|
||||
@@ -189,7 +208,7 @@ endif
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download tzfpy $(PYPI_PLATFORM) --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
|
||||
# pyradiance is using different platform versions than defaults in our makefile.
|
||||
ifeq ($(PLATFORM), linux)
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform manylinux_2_35_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform manylinux_2_28_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
|
||||
else ifeq ($(PLATFORM), macos)
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PIP) download pyradiance --platform macosx_10_13_x86_64 --python-version $(PYPI_VERSION) --implementation $(PYPI_IMP) --only-binary=:all: --dest=./wheels
|
||||
else
|
||||
@@ -206,19 +225,8 @@ endif
|
||||
cd build/bonsai/bim/data/gantt/ && wget https://raw.githubusercontent.com/jsGanttImproved/jsgantt-improved/master/dist/jsgantt.css
|
||||
|
||||
# Provides IFCJSON functionality
|
||||
cd build && wget -O ifc2json.zip https://github.com/IFCJSON-Team/IFC2JSON_python/archive/refs/heads/master.zip
|
||||
cd build && unzip ifc2json.zip && rm ifc2json.zip
|
||||
# IFCJSON doesn't have pyproject.toml, so we use python command.
|
||||
cd build && . env/$(VENV_ACTIVATE) && cd IFC2JSON_python-*/file_converters && \
|
||||
$(PYTHON) -c "from setuptools import setup; \
|
||||
setup( \
|
||||
name='ifcjson', \
|
||||
version='0.0.1', \
|
||||
author='Jan Brouwer', \
|
||||
author_email='jan@brewsky.nl', \
|
||||
packages=['ifcjson'], \
|
||||
)" bdist_wheel
|
||||
cp -r build/IFC2JSON_python-*/file_converters/dist/*.whl build/wheels/
|
||||
# TODO: Use official repo, once https://github.com/IFCJSON-Team/IFC2JSON_python/pull/8 is merged.
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PYTHON) -m pip wheel "git+https://github.com/Andrej730/IFC2JSON_python.git@pyproject_toml" --no-deps -w wheels/
|
||||
|
||||
# Brickschema requires pkg_resources which is provided by Blender.
|
||||
# Provides Brickschema functionality
|
||||
@@ -226,26 +234,16 @@ endif
|
||||
cd build/bonsai/bim/data/brick/ && wget https://github.com/BrickSchema/Brick/releases/download/nightly/Brick.ttl
|
||||
|
||||
# Required for hipped roof generation
|
||||
cd build && wget https://github.com/prochitecture/bpypolyskel/archive/refs/heads/master.zip
|
||||
cd build && unzip master.zip && rm master.zip
|
||||
cd build && . env/$(VENV_ACTIVATE) && cd bpypolyskel-master && \
|
||||
$(PYTHON) -c "from setuptools import setup; \
|
||||
setup( \
|
||||
name='bpypolyskel', \
|
||||
version='0.0.0', \
|
||||
packages=['bpypolyskel'], \
|
||||
)" bdist_wheel
|
||||
cp -r build/bpypolyskel-master/dist/*.whl build/wheels/
|
||||
cd build && . env/$(VENV_ACTIVATE) && $(PYTHON) -m pip wheel "git+https://github.com/prochitecture/bpypolyskel" --no-deps -w wheels/
|
||||
|
||||
# folder for executable files
|
||||
mkdir -p build/bonsai/libs/bin
|
||||
|
||||
# required for three-way git merging
|
||||
ifeq ($(PLATFORM), win)
|
||||
cd build/bonsai/libs/bin && wget https://github.com/brunopostle/ifcmerge/releases/download/2025-01-26/ifcmerge.zip
|
||||
cd build/bonsai/libs/bin && unzip ifcmerge.zip && rm ifcmerge.zip
|
||||
cd build/bonsai/libs/bin && wget https://github.com/brunopostle/ifcmerge/releases/download/$(IFCMERGE_VERSION)/ifcmerge.exe
|
||||
else
|
||||
cd build/bonsai/libs/bin && wget https://raw.githubusercontent.com/brunopostle/ifcmerge/main/ifcmerge && chmod +x ifcmerge
|
||||
cd build/bonsai/libs/bin && wget https://raw.githubusercontent.com/brunopostle/ifcmerge/$(IFCMERGE_VERSION)/ifcmerge && chmod +x ifcmerge
|
||||
endif
|
||||
|
||||
# Generate translations module for Bonsai build
|
||||
@@ -264,9 +262,15 @@ else
|
||||
$(SED) "s/0.0.0/$(VERSION)-alpha$(VERSION_DATE)/" build/bonsai/blender_manifest.toml
|
||||
$(SED) "s/8888888/$(LAST_COMMIT_HASH)/" build/bonsai/__init__.py
|
||||
$(SED) "s/9999999/$(LAST_COMMIT_DATE)/" build/bonsai/__init__.py
|
||||
$(SED) "s/7777777/$(LAST_GIT_BRANCH)/" build/bonsai/__init__.py
|
||||
$(SED) 's/version = "0.0.0"/version = "$(VERSION)-alpha$(VERSION_DATE)"/' build/pyproject.toml
|
||||
endif
|
||||
|
||||
# Blender 5.1+ requires Python 3.13.
|
||||
ifeq ($(PYVERSION), py313)
|
||||
$(SED) 's/blender_version_min = "4\.2\.0"/blender_version_min = "5.1.0"/' build/bonsai/blender_manifest.toml
|
||||
endif
|
||||
|
||||
$(SED) "s/os-arch/$(BLENDER_PLATFORM)/" build/bonsai/blender_manifest.toml
|
||||
|
||||
# Provides bonsai Add-on functionality
|
||||
@@ -288,12 +292,6 @@ endif
|
||||
fi
|
||||
mv build/wheels/*.whl build/bonsai/wheels/
|
||||
|
||||
# Temporary workaround for Blender not handling non-3.11 wheels #5743.
|
||||
# Use '-n' as on macos x86-64 doesn't have a binary wheel and it autoincludes 'cp311'.
|
||||
prev_whl_name=$$(find build/bonsai/wheels/tzfpy-*.whl); \
|
||||
whl_name=$$(echo $$prev_whl_name | sed "s/-cp39-/-cp$(PYNUMBER)-/"); \
|
||||
mv --update=none "$$prev_whl_name" "$$whl_name";
|
||||
|
||||
ifneq ($(PLATFORM), linux)
|
||||
# Safeguard: in case one of `pip download` will break,
|
||||
# it will produce a linux wheel for non-linux build (our github action machine is using linux).
|
||||
@@ -336,7 +334,11 @@ test:
|
||||
|
||||
.PHONY: test-core
|
||||
test-core:
|
||||
ifndef MODULE
|
||||
pytest -p no:pytest-blender test/core
|
||||
else
|
||||
pytest -p no:pytest-blender test/core/test_${MODULE}.py
|
||||
endif
|
||||
|
||||
.PHONY: test-bim
|
||||
test-bim:
|
||||
@@ -351,7 +353,7 @@ test-tool:
|
||||
ifndef MODULE
|
||||
pytest test/tool
|
||||
else
|
||||
pytest test/tool/test_$(MODULE).py
|
||||
pytest test/tool/test_$(MODULE).py --maxfail=1
|
||||
endif
|
||||
|
||||
# Reregistering test is not added to the standard test suite because during unregister
|
||||
|
||||
@@ -32,20 +32,18 @@ if IN_BLENDER:
|
||||
# and then as a bonsai-package.
|
||||
IN_PACKAGE = __package__ == "bonsai"
|
||||
|
||||
import re
|
||||
import platform
|
||||
import re
|
||||
import traceback
|
||||
import webbrowser
|
||||
import uuid
|
||||
import shutil
|
||||
from collections import deque
|
||||
from pathlib import Path
|
||||
from typing import Union, Any
|
||||
from collections.abc import Generator
|
||||
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, Union
|
||||
|
||||
last_commit_hash = "8888888"
|
||||
last_commit_date = "9999999"
|
||||
last_git_branch = "7777777"
|
||||
|
||||
|
||||
def get_last_commit_hash() -> Union[str, None]:
|
||||
@@ -63,6 +61,15 @@ def get_last_commit_date() -> Union[str, None]:
|
||||
return last_commit_date
|
||||
|
||||
|
||||
def get_git_branch() -> Union[str, None]:
|
||||
# Using this weird way to write 7777777,
|
||||
# so makefile won't accidentally replace it here
|
||||
# we'll be able to distinguish branch from placeholder value.
|
||||
if last_git_branch == str(7_777777):
|
||||
return None
|
||||
return last_git_branch
|
||||
|
||||
|
||||
# Accessed from bonsai extension:
|
||||
bbim_semver: dict[str, Any] = {}
|
||||
|
||||
@@ -74,6 +81,21 @@ REINSTALLED_BBIM_VERSION: Union[str, None] = None
|
||||
REGISTERED_BBIM_PACKAGE: str
|
||||
|
||||
|
||||
def is_registering() -> bool:
|
||||
"""
|
||||
During addon registration ``bpy.context`` and ``bpy.data`` are restricted
|
||||
and you can't access their properties.
|
||||
"""
|
||||
import bpy
|
||||
|
||||
if TYPE_CHECKING or bpy.app.version >= (5, 0, 0):
|
||||
import _bpy_restrict_state as bpy_restrict_state
|
||||
else:
|
||||
import bpy_restrict_state
|
||||
|
||||
return isinstance(bpy.context, bpy_restrict_state._RestrictContext)
|
||||
|
||||
|
||||
def initialize_bbim_semver():
|
||||
"""Initialize `bbim_semver` dictionary.
|
||||
|
||||
@@ -95,9 +117,13 @@ def initialize_bbim_semver():
|
||||
bbim_semver["version"] = version_str
|
||||
|
||||
|
||||
def get_debug_info():
|
||||
def get_debug_info(*, bonsai_failed_to_load: bool = False) -> dict[str, Any]:
|
||||
import bpy
|
||||
|
||||
bbim_version = bbim_semver["version"]
|
||||
|
||||
# All data here should be gettable even in case of `bpy.context` and `bpy.data` being inaccessible
|
||||
# and Bonsai completely failed to load.
|
||||
debug_info = {
|
||||
"os": platform.system(),
|
||||
"os_version": platform.version(),
|
||||
@@ -109,10 +135,19 @@ def get_debug_info():
|
||||
"bonsai_version": bbim_version,
|
||||
"bonsai_commit_hash": get_last_commit_hash(),
|
||||
"bonsai_commit_date": get_last_commit_date(),
|
||||
"bonsai_git_branch": get_git_branch(),
|
||||
"last_actions": last_actions,
|
||||
"last_error": last_error,
|
||||
}
|
||||
|
||||
# Can't access blend data or context during registration.
|
||||
# If Bonsai failed to load we cannot safely access any of its properties or its tools
|
||||
# as they may not be registered yet and acessing them will break Bonsai Fatal Error UI.
|
||||
if is_registering() or bonsai_failed_to_load:
|
||||
return debug_info
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
# Add .blend file save information
|
||||
if bpy.data.is_saved:
|
||||
debug_info["blend_file_path"] = bpy.data.filepath
|
||||
@@ -133,7 +168,7 @@ def get_debug_info():
|
||||
return debug_info
|
||||
|
||||
|
||||
def format_debug_info(info: dict):
|
||||
def format_debug_info(info: dict[str, Any]) -> str:
|
||||
last_actions = ""
|
||||
for action in info["last_actions"]:
|
||||
last_actions += f"\n# {action['type']}: {action['name']}"
|
||||
@@ -151,33 +186,10 @@ def get_binaries(path: Path) -> Generator[Path, None, None]:
|
||||
yield from path.glob("**/*.so")
|
||||
|
||||
|
||||
def safe_link_dlls() -> None:
|
||||
# Blender 4.2+ has a problem on Windows for disabling/enabling/reinstalling extensions
|
||||
# with loaded binary dependencies (on Windows you can't remove a binary if it's loaded by some program).
|
||||
# To avoid this issue we temporary hard link dlls to our temp directory on unregister()
|
||||
# (unregister is executed before Blender will try to uninstall dependencies and the issue will arise).
|
||||
# Then, Blender won't have a problem unlinking unloaded dlls as they are still linked somewhere.
|
||||
# On register() we clean up our temp directory with binaries.
|
||||
#
|
||||
# TODO: If user uninstalls Bonsai to never use it again, temporary directory won't be cleared.
|
||||
#
|
||||
# See: https://projects.blender.org/blender/blender/issues/125049
|
||||
import bpy
|
||||
|
||||
ext_path = Path(bpy.utils.user_resource("EXTENSIONS"))
|
||||
local_path = ext_path / ".local"
|
||||
|
||||
# We use random hash subfolder as user may try to enable/disable addon multiple times.
|
||||
random_hash = uuid.uuid4().hex[:8]
|
||||
temp_local = ext_path / ".local_temp" / random_hash
|
||||
temp_local.mkdir(parents=True)
|
||||
|
||||
for filepath in get_binaries(local_path):
|
||||
dest_path = temp_local / filepath.relative_to(local_path)
|
||||
dest_path.parent.mkdir(exist_ok=True, parents=True)
|
||||
os.link(filepath, dest_path)
|
||||
|
||||
|
||||
# TODO: remove before 0.8.6 release.
|
||||
# On Windows issues with removing extensions were resolved in Blender 4.3,
|
||||
# but we removed our workaround that was producing some junk only in 0.8.5 release.
|
||||
# So we're temporarily keeping the part that's cleaning up outputs from previous releases.
|
||||
def clean_up_dlls_safe_links() -> None:
|
||||
import bpy
|
||||
|
||||
@@ -207,6 +219,8 @@ def clean_up_dlls_safe_links() -> None:
|
||||
|
||||
|
||||
if IN_BLENDER:
|
||||
import bpy
|
||||
|
||||
initialize_bbim_semver()
|
||||
|
||||
def get_binary_info() -> dict[str, Any]:
|
||||
@@ -248,10 +262,12 @@ if IN_BLENDER:
|
||||
|
||||
global last_commit_hash
|
||||
global last_commit_date
|
||||
global last_git_branch
|
||||
path = Path(__file__).resolve().parent
|
||||
repo = git.Repo(str(path), search_parent_directories=True)
|
||||
last_commit_hash = repo.head.object.hexsha
|
||||
last_commit_date = repo.head.object.committed_datetime.isoformat()
|
||||
last_git_branch = repo.active_branch.name
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -298,9 +314,6 @@ if IN_BLENDER:
|
||||
purge_cache()
|
||||
|
||||
def unregister():
|
||||
if platform.system() == "Windows":
|
||||
safe_link_dlls()
|
||||
|
||||
import bonsai.bim
|
||||
|
||||
bonsai.bim.unregister()
|
||||
@@ -335,7 +348,7 @@ if IN_BLENDER:
|
||||
bl_context = "scene"
|
||||
|
||||
def draw(self, context):
|
||||
info = get_debug_info()
|
||||
info = get_debug_info(bonsai_failed_to_load=True)
|
||||
|
||||
layout = self.layout
|
||||
layout.alert = True
|
||||
@@ -411,7 +424,7 @@ if IN_BLENDER:
|
||||
bl_description = "Copies debugging information to your clipboard for use in bugreports"
|
||||
|
||||
def execute(self, context):
|
||||
info = get_debug_info()
|
||||
info = get_debug_info(bonsai_failed_to_load=True)
|
||||
info.update(get_binary_info())
|
||||
info = format_debug_info(info)
|
||||
context.window_manager.clipboard = info
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import importlib
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
from typing import Union
|
||||
|
||||
import bpy
|
||||
import bpy.utils.previews
|
||||
import importlib
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
from . import handler, ui, prop, operator
|
||||
from typing import Union
|
||||
from collections.abc import Callable
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
from . import handler, operator, prop, ui
|
||||
|
||||
try:
|
||||
from bonsai.translations import translations_dict
|
||||
@@ -120,6 +122,7 @@ classes = [
|
||||
operator.OpenUri,
|
||||
operator.ReloadIfcFile,
|
||||
operator.RevertClippingPlaneCut,
|
||||
operator.SaveBlendMetadataFile,
|
||||
operator.SelectDir,
|
||||
operator.SelectIfcFile,
|
||||
operator.SelectURIAttribute,
|
||||
@@ -129,12 +132,16 @@ classes = [
|
||||
prop.StrProperty,
|
||||
operator.BIM_OT_enum_property_search, # /!\ Register AFTER prop.StrProperty
|
||||
operator.BIM_OT_attribute_search_values,
|
||||
operator.BIM_OT_manage_tab_visibility,
|
||||
operator.BIM_OT_reset_ui_layout,
|
||||
prop.ObjProperty,
|
||||
prop.MultipleFileSelect,
|
||||
prop.Attribute,
|
||||
prop.ISODuration,
|
||||
prop.BIMAreaProperties,
|
||||
prop.BIMTabProperties,
|
||||
prop.BIMTabVisibility, # Must be registered before BIMProperties
|
||||
prop.BIMPanelVisibility, # Must be registered before BIMProperties
|
||||
prop.BIMProperties,
|
||||
prop.IfcParameter,
|
||||
prop.PsetQto,
|
||||
@@ -147,6 +154,8 @@ classes = [
|
||||
prop.BIMSnapGroups,
|
||||
ui.BIM_UL_clipping_plane,
|
||||
ui.BIM_UL_generic,
|
||||
ui.BIM_UL_tab_visibilities,
|
||||
ui.BIM_UL_panel_visibilities,
|
||||
ui.DocPreferences,
|
||||
ui.GizmoPreferencesDoor, # Register before GizmoPreferences
|
||||
ui.GizmoPreferencesWindow, # Register before GizmoPreferences
|
||||
@@ -272,6 +281,7 @@ def register():
|
||||
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)
|
||||
|
||||
if hasattr(bpy.types, "UI_MT_button_context_menu"):
|
||||
bpy.types.UI_MT_button_context_menu.append(ui.draw_custom_context_menu)
|
||||
bpy.types.STATUSBAR_HT_header.append(ui.draw_statusbar)
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
* { stroke-linecap: round; stroke-linejoin: round; }
|
||||
text, tspan { /* 2.5mm */ fill: black; stroke: none; font-family: 'OpenGost Type B TT', 'DejaVu Sans Condensed', 'Liberation Sans', 'Arial Narrow', 'Arial'; font-size: 4.13px; }
|
||||
a text, a tspan { fill: blue !important; text-decoration: underline;}
|
||||
a:hover { cursor: pointer; }
|
||||
.cut { fill: black; stroke: black; stroke-linecap: 'round'; stroke-width: 0.35; fill-rule: evenodd; }
|
||||
.projection { fill: white; stroke: black; stroke-linecap: 'round'; stroke-width: 0.25; }
|
||||
.surface { stroke: none; fill: #fff; fill-rule: evenodd; }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
import sys
|
||||
|
||||
bonsai_lib_path = os.environ.get("BONSAI_LIB_PATH")
|
||||
bonsai_version = os.environ.get("BONSAI_VERSION")
|
||||
@@ -9,13 +8,14 @@ if bonsai_lib_path:
|
||||
sys.path.insert(0, bonsai_lib_path)
|
||||
|
||||
import argparse
|
||||
from aiohttp import web
|
||||
import socketio
|
||||
import pystache
|
||||
import json
|
||||
import base64
|
||||
import json
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import pystache
|
||||
import socketio
|
||||
from aiohttp import web
|
||||
|
||||
sio_port = 8080 # default port
|
||||
|
||||
sio = socketio.AsyncServer(cors_allowed_origins="*", async_mode="aiohttp", max_http_buffer_size=10000000)
|
||||
|
||||
@@ -17,27 +17,23 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
|
||||
import datetime
|
||||
import zipfile
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.unit
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.geometry
|
||||
import bonsai.core.aggregate
|
||||
import bonsai.core.spatial
|
||||
import bonsai.core.style
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from mathutils import Vector
|
||||
from typing import Union
|
||||
import zipfile
|
||||
from logging import Logger
|
||||
from math import radians
|
||||
from typing import Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
import bonsai.core.geometry
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
|
||||
class IfcExporter:
|
||||
@@ -49,7 +45,6 @@ class IfcExporter:
|
||||
self.set_header()
|
||||
IfcStore.update_cache()
|
||||
self.sync_all_objects()
|
||||
tool.Project.save_linked_models_to_ifc()
|
||||
extension = self.ifc_export_settings.output_file.split(".")[-1].lower()
|
||||
if extension == "ifczip":
|
||||
with tempfile.TemporaryDirectory() as unzipped_path:
|
||||
@@ -77,9 +72,7 @@ class IfcExporter:
|
||||
|
||||
def set_header(self):
|
||||
self.file.header.file_name.name = os.path.basename(self.ifc_export_settings.output_file)
|
||||
self.file.header.file_name.time_stamp = (
|
||||
datetime.datetime.utcnow().replace(tzinfo=datetime.UTC).astimezone().replace(microsecond=0).isoformat()
|
||||
)
|
||||
self.file.header.file_name.time_stamp = datetime.datetime.now().astimezone().replace(microsecond=0).isoformat()
|
||||
self.file.header.file_name.preprocessor_version = "IfcOpenShell {}".format(ifcopenshell.version)
|
||||
self.file.header.file_name.originating_system = "{} {}".format(
|
||||
self.get_application_name(), tool.Blender.get_bonsai_version()
|
||||
|
||||
@@ -17,39 +17,47 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import weakref
|
||||
from collections.abc import Callable
|
||||
from math import cos
|
||||
from typing import Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.api.owner.settings
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.api.owner.settings
|
||||
from bpy.app.handlers import persistent
|
||||
from mathutils import Vector
|
||||
|
||||
import bonsai.bim
|
||||
import bonsai.tool as tool
|
||||
import weakref
|
||||
from bpy.app.handlers import persistent
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bonsai.bim.module.aggregate.decorator import AggregateDecorator
|
||||
from bonsai.bim.module.georeference.decorator import GeoreferenceDecorator
|
||||
from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator, BoundingBoxDecorator
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bonsai.bim.module.model.decorator import (
|
||||
BoundingBoxDecorator,
|
||||
SlabDirectionDecorator,
|
||||
WallAxisDecorator,
|
||||
)
|
||||
from bonsai.bim.module.nest.decorator import NestDecorator
|
||||
from mathutils import Vector
|
||||
from math import cos
|
||||
from typing import Union
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
global_subscription_owner = object()
|
||||
# Separate owner for per-object msgbus subscriptions (name, active_material_index).
|
||||
# Using a dedicated owner allows clearing all per-object subscriptions at once
|
||||
# during undo/redo without affecting other global subscriptions.
|
||||
object_subscription_owner = object()
|
||||
|
||||
|
||||
def name_callback(obj: Union[bpy.types.Object, bpy.types.Material], data: str) -> None:
|
||||
try:
|
||||
obj.name
|
||||
except:
|
||||
# The object is invalid but somehow still has a callback. Clear all
|
||||
# msgbus subscriptions to prevent useless further triggers.
|
||||
bpy.msgbus.clear_by_owner(obj)
|
||||
return # In case the object RNA is gone during an undo / redo operation
|
||||
# The object is invalid but somehow still has a callback.
|
||||
# This can occur during undo/redo when the Python wrapper is stale.
|
||||
return
|
||||
# Blender names are up to 63 UTF-8 bytes
|
||||
if len(bytes(obj.name, "utf-8")) >= 63:
|
||||
return
|
||||
@@ -184,7 +192,7 @@ def subscribe_to(obj: bpy.types.ID, data_path: str, callback: Callable[[bpy.type
|
||||
return
|
||||
bpy.msgbus.subscribe_rna(
|
||||
key=subscribe_to,
|
||||
owner=obj,
|
||||
owner=object_subscription_owner,
|
||||
args=(
|
||||
obj,
|
||||
data_path,
|
||||
@@ -202,8 +210,8 @@ def refresh_ui_data():
|
||||
Note that calling non-ifc-operators by itself doesn't refresh the UI data
|
||||
and it need to be refreshed manually if needed.
|
||||
"""
|
||||
from bonsai.bim import modules
|
||||
import bonsai.bim.ui
|
||||
from bonsai.bim import modules
|
||||
|
||||
bonsai.bim.ui.refresh()
|
||||
|
||||
|
||||
+241
-19
@@ -17,24 +17,30 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import bpy
|
||||
import json
|
||||
from collections.abc import Callable, Iterable, Sequence
|
||||
from types import EllipsisType
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.ifcopenshell_wrapper as W
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
from ifcopenshell.util.doc import get_attribute_doc, get_predefined_type_doc, get_property_doc
|
||||
from ifcopenshell.util.doc import (
|
||||
get_attribute_doc,
|
||||
get_predefined_type_doc,
|
||||
get_property_doc,
|
||||
)
|
||||
|
||||
import bonsai.tool as tool
|
||||
from types import EllipsisType
|
||||
from typing import Optional, Any, Union, TYPE_CHECKING
|
||||
from collections.abc import Callable, Iterable, Sequence
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import bonsai.bim.prop
|
||||
from bonsai.bim.prop import Attribute
|
||||
from bonsai.bim.module.search.prop import BIMFilterGroup
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
# ImportCallback return values:
|
||||
# - None - property should be imported by default workflow
|
||||
@@ -428,7 +434,11 @@ def get_enum_items(
|
||||
else:
|
||||
annotations_data = data
|
||||
|
||||
prop = annotations_data.__annotations__[prop_name]
|
||||
try:
|
||||
annotations = annotations_data.__annotations__
|
||||
except AttributeError:
|
||||
annotations = type(annotations_data).__annotations__
|
||||
prop = annotations[prop_name]
|
||||
items = prop.keywords.get("items")
|
||||
if items is None:
|
||||
return
|
||||
@@ -498,6 +508,8 @@ def draw_filter(
|
||||
if data.data["saved_searches"]:
|
||||
row.operator("bim.load_search", text="", icon="IMPORT").module = module
|
||||
row.operator("bim.save_search", text="", icon="EXPORT").module = module
|
||||
if data.data["saved_searches"]:
|
||||
row.operator("bim.remove_search", text="", icon="REMOVE").module = module
|
||||
if module != "search":
|
||||
if module == "drawing_include":
|
||||
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "INCLUDE"
|
||||
@@ -505,62 +517,272 @@ def draw_filter(
|
||||
row.operator("bim.edit_element_filter", icon="CHECKMARK", text="").filter_mode = "EXCLUDE"
|
||||
row.operator("bim.enable_editing_element_filter", icon="CANCEL", text="").filter_mode = "NONE"
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
|
||||
row.operator("bim.edit_filter_query", text="", icon="FILTER").module = module
|
||||
preferences = tool.Blender.get_addon_preferences()
|
||||
if not preferences.chain_filter_with_set_operations:
|
||||
row.operator("bim.add_filter_group", text="Add Search Group", icon="ADD").module = module
|
||||
else:
|
||||
row.prop(sprops, "facet", text="")
|
||||
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
|
||||
op.type = sprops.facet
|
||||
op.index = 0
|
||||
op.module = module
|
||||
op = row.operator("bim.edit_filter_query", text="", icon="FILTER")
|
||||
if "module" in op.bl_rna.properties:
|
||||
op.module = module
|
||||
|
||||
for i, filter_group in enumerate(filter_groups):
|
||||
box = layout.box()
|
||||
|
||||
row = box.row(align=True)
|
||||
row.prop(sprops, "facet", text="")
|
||||
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
|
||||
op.type = sprops.facet
|
||||
op.index = i
|
||||
op.module = module
|
||||
op = row.operator("bim.remove_filter_group", text="", icon="X")
|
||||
op.index = i
|
||||
op.module = module
|
||||
preferences = tool.Blender.get_addon_preferences()
|
||||
if not preferences.chain_filter_with_set_operations:
|
||||
row = box.row(align=True)
|
||||
row.prop(sprops, "facet", text="")
|
||||
op = row.operator("bim.add_filter", text="Add Filter", icon="ADD")
|
||||
op.type = sprops.facet
|
||||
op.index = i
|
||||
op.module = module
|
||||
op = row.operator("bim.remove_filter_group", text="", icon="X")
|
||||
op.index = i
|
||||
op.module = module
|
||||
|
||||
for j, ifc_filter in enumerate(filter_group.filters):
|
||||
if ifc_filter.type == "entity":
|
||||
row = box.row(align=True)
|
||||
preferences = tool.Blender.get_addon_preferences()
|
||||
show_mode_toggle = preferences.chain_filter_with_set_operations and j > 0
|
||||
if show_mode_toggle:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="FILE_3D")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "attribute":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "name", text="", icon="COPY_ID")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op.suggestion_type = "attribute_name"
|
||||
row.prop(ifc_filter, "value", text="")
|
||||
if ifc_filter.name:
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op.suggestion_type = "attribute_value"
|
||||
elif ifc_filter.type == "type":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="FILE_VOLUME")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "material":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="MATERIAL")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "property":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "pset", text="", icon="PROPERTIES")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op.suggestion_type = "pset"
|
||||
row.prop(ifc_filter, "name", text="")
|
||||
if ifc_filter.pset:
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op.suggestion_type = "property_name"
|
||||
row.prop(ifc_filter, "comparison", text="")
|
||||
row.prop(ifc_filter, "value", text="")
|
||||
if ifc_filter.pset and ifc_filter.name:
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op.suggestion_type = "property_value"
|
||||
elif ifc_filter.type == "classification":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="OUTLINER")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "location":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="PACKAGE")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "group":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="OUTLINER_COLLECTION")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "parent":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="FILE_PARENT")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
elif ifc_filter.type == "query":
|
||||
row = box.row(align=True)
|
||||
if tool.Blender.get_addon_preferences().chain_filter_with_set_operations and j > 0:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "name", text="", icon="POINTCLOUD_DATA")
|
||||
row.prop(ifc_filter, "comparison", text="")
|
||||
row.prop(ifc_filter, "value", text="")
|
||||
elif ifc_filter.type == "instance":
|
||||
row = box.row(align=True)
|
||||
preferences = tool.Blender.get_addon_preferences()
|
||||
show_mode_toggle = preferences.chain_filter_with_set_operations and j > 0
|
||||
if show_mode_toggle:
|
||||
mode_icons = {"ADD": "ADD", "SUBTRACT": "REMOVE", "FILTER": "FILTER"}
|
||||
op = row.operator(
|
||||
"bim.toggle_filter_inclusion",
|
||||
icon=mode_icons.get(ifc_filter.filter_mode, "ADD"),
|
||||
text="",
|
||||
depress=ifc_filter.filter_mode != "ADD",
|
||||
)
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
row.prop(ifc_filter, "value", text="", icon="GRIP")
|
||||
op = row.operator("bim.filter_value_suggestions", text="", icon="VIEWZOOM")
|
||||
op.group_index = i
|
||||
op.filter_index = j
|
||||
op.module = module
|
||||
op.filter_type = ifc_filter.type
|
||||
op = row.operator("bim.select_filter_elements", text="", icon="EYEDROPPER")
|
||||
op.group_index = i
|
||||
op.index = j
|
||||
|
||||
@@ -17,26 +17,28 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import bpy
|
||||
import uuid
|
||||
import shutil
|
||||
|
||||
import hashlib
|
||||
import zipfile
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import traceback
|
||||
import uuid
|
||||
import zipfile
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Literal, NotRequired, Optional, TypedDict, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.ifcopenshell_wrapper
|
||||
from ifcopenshell.file import UndoSystemError
|
||||
|
||||
import bonsai
|
||||
import bonsai.bim.handler
|
||||
import bonsai.tool as tool
|
||||
from ifcopenshell.file import UndoSystemError
|
||||
from pathlib import Path
|
||||
from bonsai.tool.brick import BrickStore
|
||||
from typing import Union, Optional, TypedDict, NotRequired, Literal
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
IFC_CONNECTED_TYPE = Union[bpy.types.Material, bpy.types.Object]
|
||||
|
||||
@@ -314,11 +316,8 @@ class IfcStore:
|
||||
del IfcStore.id_map[data["id"]]
|
||||
if "guid" in data:
|
||||
del IfcStore.guid_map[data["guid"]]
|
||||
obj = IfcStore.get_object_by_name(data["obj"])
|
||||
if obj is None:
|
||||
# obj was just created during this step and didn't existed before.
|
||||
return
|
||||
bpy.msgbus.clear_by_owner(obj)
|
||||
# Note: msgbus subscriptions are cleared globally during
|
||||
# rebuild_element_maps which runs after every undo/redo.
|
||||
|
||||
@staticmethod
|
||||
def commit_link_element(data: OperationData) -> None:
|
||||
@@ -365,10 +364,8 @@ class IfcStore:
|
||||
del IfcStore.id_map[data["id"]]
|
||||
if "guid" in data:
|
||||
del IfcStore.guid_map[data["guid"]]
|
||||
obj = IfcStore.get_object_by_name(data["obj"])
|
||||
# obj might be removed after unlink.
|
||||
if not obj:
|
||||
bpy.msgbus.clear_by_owner(obj)
|
||||
# Note: msgbus subscriptions are cleared globally during
|
||||
# rebuild_element_maps which runs after every undo/redo.
|
||||
|
||||
@staticmethod
|
||||
def unlink_element(
|
||||
|
||||
@@ -17,33 +17,35 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import time
|
||||
|
||||
import json
|
||||
import ifcpatch
|
||||
import logging
|
||||
import traceback
|
||||
import mathutils
|
||||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
import multiprocessing
|
||||
import time
|
||||
import traceback
|
||||
from collections.abc import Iterable
|
||||
from typing import Any, Literal, Optional, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.ifcopenshell_wrapper as W
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.shape
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
|
||||
from bonsai.tool.loader import OBJECT_DATA_TYPE
|
||||
from typing import Union, Optional, Any, Literal
|
||||
from collections.abc import Iterable
|
||||
import ifcopenshell.util.unit
|
||||
import ifcpatch
|
||||
import mathutils
|
||||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
from ifcopenshell.util.shape import MatrixType
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IFC_CONNECTED_TYPE, IfcStore
|
||||
from bonsai.tool.loader import OBJECT_DATA_TYPE
|
||||
|
||||
|
||||
class MaterialCreator:
|
||||
mesh: bpy.types.Mesh
|
||||
@@ -62,8 +64,8 @@ class MaterialCreator:
|
||||
mesh: Union[OBJECT_DATA_TYPE, None],
|
||||
shape_has_openings: bool,
|
||||
) -> None:
|
||||
if ((rep := getattr(element, "Representation", ...) is not ...) and not rep) or (
|
||||
(rep := getattr(element, "RepresentationMaps", ...) is not ...) and not rep
|
||||
if ((rep := getattr(element, "Representation", ...)) is not ... and not rep) or (
|
||||
(rep := getattr(element, "RepresentationMaps", ...)) is not ... and not rep
|
||||
):
|
||||
return
|
||||
|
||||
@@ -82,7 +84,7 @@ class MaterialCreator:
|
||||
if element.is_a("IfcTypeProduct"):
|
||||
self.parse_element_type_material_styles(element)
|
||||
self.parsed_meshes.add(self.mesh.name)
|
||||
if not self.ifc_import_settings.load_indexed_maps:
|
||||
if self.ifc_import_settings.load_indexed_maps:
|
||||
self.load_texture_maps(shape_has_openings)
|
||||
self.assign_material_slots_to_faces()
|
||||
tool.Geometry.record_object_materials(obj)
|
||||
@@ -114,7 +116,6 @@ class MaterialCreator:
|
||||
for texture in texture_style.Textures or []:
|
||||
if coords := getattr(texture, "IsMappedBy", None):
|
||||
coords = coords[0]
|
||||
# IfcTextureCoordinateGenerator handled in the style shader graph
|
||||
if coords.is_a("IfcIndexedTextureMap"):
|
||||
return coords
|
||||
# TODO: support IfcTextureMap
|
||||
@@ -132,6 +133,10 @@ class MaterialCreator:
|
||||
if shape_has_openings and coords.is_a("IfcIndexedTextureMap"):
|
||||
continue
|
||||
tool.Loader.load_indexed_map(coords, self.mesh)
|
||||
elif tool.Style.get_texture_style(material):
|
||||
# No explicit coordinate mapping (e.g. IFC2X3 has no IsMappedBy,
|
||||
# and IFC4 COORD uses generated UVs). Bake XY→UV as fallback.
|
||||
tool.Loader.load_generated_uv_map(self.mesh)
|
||||
|
||||
def assign_material_slots_to_faces(self) -> None:
|
||||
if not self.mesh["ios_materials"]:
|
||||
@@ -742,6 +747,7 @@ class IfcImporter:
|
||||
self.update_progress((percent_average / 100 * progress_range) + start_progress)
|
||||
shape = iterator.get()
|
||||
if shape:
|
||||
assert isinstance(shape, W.TriangulationElement)
|
||||
product = self.file.by_id(shape.id)
|
||||
self.create_product(product, shape)
|
||||
results.add(product)
|
||||
@@ -1015,7 +1021,8 @@ class IfcImporter:
|
||||
obj.hide_select = True
|
||||
obj.hide_viewport = True
|
||||
self.project["blender"].objects.link(obj)
|
||||
self.project["blender"].BIMCollectionProperties.obj = obj
|
||||
collection_props = tool.Blender.get_collection_props(self.project["blender"])
|
||||
collection_props.obj = obj
|
||||
props = tool.Blender.get_object_bim_props(obj)
|
||||
props.collection = self.collections[project.GlobalId] = self.project["blender"]
|
||||
|
||||
@@ -1261,7 +1268,7 @@ class IfcImportSettings:
|
||||
self.should_load_geometry = True
|
||||
self.should_clean_mesh = False
|
||||
self.should_cache = True
|
||||
self.deflection_tolerance = 0.001
|
||||
self.deflection_tolerance = 0.05 # Default is 0.001, but I find this to be more practical
|
||||
self.angular_tolerance = 0.5
|
||||
self.void_limit = 30
|
||||
self.style_limit = 300
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.BIM_OT_add_aggregate,
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
import ifcopenshell.util.element
|
||||
from typing import Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.element
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def refresh():
|
||||
AggregateData.is_loaded = False
|
||||
|
||||
@@ -19,14 +19,13 @@
|
||||
import blf
|
||||
import bpy
|
||||
import gpu
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import SpaceView3D
|
||||
from bpy_extras import view3d_utils
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
from mathutils import Vector
|
||||
from bonsai.bim.module.geometry.decorator import ItemDecorator
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def transparent_color(color, alpha=0.1):
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.group
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.util.element
|
||||
import bonsai.tool as tool
|
||||
|
||||
import bonsai.core.aggregate as core
|
||||
import bonsai.core.spatial
|
||||
from typing import TYPE_CHECKING
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class BIM_OT_aggregate_assign_object(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -222,7 +222,7 @@ class BIM_OT_add_aggregate(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Collector,
|
||||
tool.Spatial,
|
||||
container=current_container,
|
||||
element_obj=aggregate,
|
||||
objs=[aggregate],
|
||||
)
|
||||
core.assign_object(tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=aggregate, related_obj=obj)
|
||||
|
||||
|
||||
@@ -16,24 +16,22 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.element
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bonsai.bim.module.spatial.data import SpatialData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.aggregate.decorator import (
|
||||
AggregateDecorator,
|
||||
AggregateModeDecorator,
|
||||
)
|
||||
from bonsai.bim.module.aggregate.decorator import AggregateDecorator, AggregateModeDecorator
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
|
||||
def can_aggregate(relating_obj: bpy.types.Object, related_obj: bpy.types.Object) -> bool:
|
||||
@@ -75,6 +73,22 @@ def poll_related_object(self: "BIMObjectAggregateProperties", related_obj: bpy.t
|
||||
return True
|
||||
|
||||
|
||||
def update_relating_object(self, context):
|
||||
if self.relating_object:
|
||||
ifc_id = tool.Blender.get_object_bim_props(self.relating_object).ifc_definition_id
|
||||
if ifc_id:
|
||||
bpy.ops.bim.aggregate_assign_object(relating_object=ifc_id)
|
||||
bpy.ops.bim.disable_editing_aggregate()
|
||||
|
||||
|
||||
def update_related_object(self, context):
|
||||
if self.related_object:
|
||||
ifc_id = tool.Blender.get_object_bim_props(self.related_object).ifc_definition_id
|
||||
if ifc_id:
|
||||
bpy.ops.bim.aggregate_assign_object(related_object=ifc_id)
|
||||
bpy.ops.bim.disable_editing_aggregate()
|
||||
|
||||
|
||||
def update_aggregate_decorator(self, context):
|
||||
if self.aggregate_decorator:
|
||||
AggregateDecorator.install(bpy.context)
|
||||
@@ -91,12 +105,15 @@ def update_aggregate_mode_decorator(self, context):
|
||||
|
||||
class BIMObjectAggregateProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
relating_object: PointerProperty(name="Relating Whole", type=bpy.types.Object, poll=poll_relating_object)
|
||||
relating_object: PointerProperty(
|
||||
name="Relating Whole", type=bpy.types.Object, poll=poll_relating_object, update=update_relating_object
|
||||
)
|
||||
related_object: PointerProperty(
|
||||
name="Related Part",
|
||||
description="Related Part, will be used to derive the Relating Object",
|
||||
type=bpy.types.Object,
|
||||
poll=poll_related_object,
|
||||
update=update_related_object,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from bpy.types import Panel
|
||||
from bonsai.bim.module.aggregate.data import AggregateData
|
||||
from bonsai.bim.module.group.data import GroupsData, ObjectGroupsData
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.aggregate.data import AggregateData
|
||||
|
||||
|
||||
class BIM_PT_aggregate(Panel):
|
||||
|
||||
@@ -18,26 +18,16 @@
|
||||
|
||||
# pyright: reportUnnecessaryTypeIgnoreComment=error
|
||||
|
||||
import os
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import time
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import time
|
||||
import calendar
|
||||
import isodate
|
||||
import bonsai.core.sequence as core
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.sequence.helper as helper
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.spatial
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.sequence
|
||||
import ifcopenshell.util.selector
|
||||
from datetime import datetime
|
||||
from dateutil import parser, relativedelta
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class ImportAlignmentCSV(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
||||
bl_idname = "bim.import_alignment_csv"
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.EnableEditingAttributes,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -16,22 +16,25 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import json
|
||||
from typing import TYPE_CHECKING, Any, Literal, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.attribute
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.attribute as core
|
||||
import bonsai.core.spatial
|
||||
from typing import TYPE_CHECKING, Any, Union, Literal
|
||||
import bonsai.tool as tool
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.prop import Attribute
|
||||
import bpy.stub_internal.rna_enums as rna_enums
|
||||
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
def get_objs_for_operation(
|
||||
operator_properties: "AttributesOperator", context: bpy.types.Context
|
||||
@@ -292,13 +295,13 @@ class ExplorerShowUIPopup(bpy.types.Operator):
|
||||
bl_description = "Show Explorer UI to select element as attribute value or edit it."
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
ifc_class: bpy.props.StringProperty() # pyright: ignore[reportRedeclaration]
|
||||
ifc_class: bpy.props.StringProperty()
|
||||
"""Element IFC class."""
|
||||
attribute_name: bpy.props.StringProperty() # pyright: ignore[reportRedeclaration]
|
||||
attribute_name: bpy.props.StringProperty()
|
||||
"""IFC class attribute name."""
|
||||
data_path: bpy.props.StringProperty() # pyright: ignore[reportRedeclaration]
|
||||
data_path: bpy.props.StringProperty()
|
||||
"""Full data path"""
|
||||
preselect_ifc_id: bpy.props.IntProperty(options={"SKIP_SAVE"}) # pyright: ignore[reportRedeclaration]
|
||||
preselect_ifc_id: bpy.props.IntProperty(options={"SKIP_SAVE"})
|
||||
"""IFC id to preselect in the popup."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -16,22 +16,20 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
class BIMAttributeProperties(PropertyGroup):
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
@@ -43,7 +41,7 @@ class BIMAttributeProperties(PropertyGroup):
|
||||
|
||||
|
||||
class ExplorerEntity(PropertyGroup):
|
||||
ifc_definition_id: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
||||
ifc_definition_id: bpy.props.IntProperty()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
ifc_definition_id: int
|
||||
@@ -62,7 +60,7 @@ class BIMExplorerProperties(PropertyGroup):
|
||||
self.property_unset("editing_entity_id")
|
||||
self.entity_attributes.clear()
|
||||
|
||||
is_loaded: BoolProperty( # pyright: ignore[reportRedeclaration]
|
||||
is_loaded: BoolProperty(
|
||||
name="Toggle Explorer UI",
|
||||
update=update_is_loaded,
|
||||
)
|
||||
@@ -78,15 +76,15 @@ class BIMExplorerProperties(PropertyGroup):
|
||||
def update_ifc_class(self, context: object) -> None:
|
||||
tool.Attribute.refresh_uilist_entities()
|
||||
|
||||
ifc_class: EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
ifc_class: EnumProperty(
|
||||
name="IFC Class To Search",
|
||||
items=get_ifc_class,
|
||||
update=update_ifc_class,
|
||||
)
|
||||
entities: CollectionProperty(type=ExplorerEntity) # pyright: ignore[reportRedeclaration]
|
||||
active_entity_index: IntProperty() # pyright: ignore[reportRedeclaration]
|
||||
editing_entity_id: IntProperty() # pyright: ignore[reportRedeclaration]
|
||||
entity_attributes: CollectionProperty(type=Attribute) # pyright: ignore[reportRedeclaration]
|
||||
entities: CollectionProperty(type=ExplorerEntity)
|
||||
active_entity_index: IntProperty()
|
||||
editing_entity_id: IntProperty()
|
||||
entity_attributes: CollectionProperty(type=Attribute)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_loaded: bool
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bonsai.bim.helper
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy.types
|
||||
from bpy.types import Panel
|
||||
from bonsai.bim.module.attribute.data import AttributesData
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING
|
||||
from bonsai.bim.module.attribute.data import AttributesData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.attribute.prop import BIMExplorerProperties, ExplorerEntity
|
||||
@@ -58,7 +61,7 @@ def draw_ui(context: bpy.types.Context, layout: bpy.types.UILayout, attributes)
|
||||
|
||||
|
||||
class BIM_PT_object_attributes(Panel):
|
||||
bl_label = "Attributes"
|
||||
bl_label = "Object Attributes"
|
||||
bl_idname = "BIM_PT_object_attributes"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
prop.AuginProperties,
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import bpy
|
||||
import string
|
||||
import random
|
||||
import shutil
|
||||
import requests
|
||||
import string
|
||||
import tempfile
|
||||
import datetime
|
||||
|
||||
import bpy
|
||||
import requests
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy.props
|
||||
import bpy.types
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class AuginProperties(bpy.types.PropertyGroup):
|
||||
@@ -27,3 +28,11 @@ class AuginProperties(bpy.types.PropertyGroup):
|
||||
project_name: bpy.props.StringProperty(name="Project Name")
|
||||
project_filename: bpy.props.StringProperty(name="IFC Filename")
|
||||
is_success: bpy.props.BoolProperty(name="Is Successful Upload", default=False)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
username: str
|
||||
password: str
|
||||
token: str
|
||||
project_name: str
|
||||
project_filename: str
|
||||
is_success: bool
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy.types
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.ActivateBcfViewpoint,
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import bcf
|
||||
import bcf.bcfxml
|
||||
import bcf.v2.bcfxml
|
||||
import bonsai.tool as tool
|
||||
from typing import Union
|
||||
|
||||
import bcf.bcfxml
|
||||
import bpy
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class BcfStore:
|
||||
bcfxml: Union[bcf.bcfxml.BcfXml, None] = None
|
||||
|
||||
@@ -16,38 +16,35 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bcf.v3
|
||||
import tempfile
|
||||
import uuid
|
||||
import webbrowser
|
||||
from math import atan, degrees, radians, tan
|
||||
from pathlib import Path
|
||||
|
||||
import bcf.agnostic.topic
|
||||
import bcf.agnostic.visinfo
|
||||
import bcf.v2.bcfxml
|
||||
import bcf.v2.model
|
||||
import bcf.v2.topic
|
||||
import bcf.v2.visinfo
|
||||
import bcf.v3.bcfxml
|
||||
import bcf.v3.document
|
||||
import bcf.v3.model
|
||||
import bcf.v3.topic
|
||||
import bcf.v3.visinfo
|
||||
import bpy
|
||||
import bcf
|
||||
import bcf.bcfxml
|
||||
import bcf.v2.bcfxml
|
||||
import bcf.v2.model
|
||||
import bcf.v2.topic
|
||||
import bcf.v2.visinfo
|
||||
import bcf.agnostic.topic
|
||||
import bcf.agnostic.visinfo
|
||||
import uuid
|
||||
import numpy as np
|
||||
import tempfile
|
||||
import webbrowser
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.geolocation
|
||||
import ifcopenshell.util.unit
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.bcf.prop as bcf_prop
|
||||
import bonsai.bim.module.bcf.bcfstore as bcfstore
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
from pathlib import Path
|
||||
from math import radians, degrees, atan, tan, cos, sin
|
||||
from mathutils import Vector, Matrix, Euler, geometry
|
||||
import numpy as np
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
from mathutils import Matrix, Vector
|
||||
from xsdata.models.datatype import XmlDateTime
|
||||
|
||||
import bonsai.bim.module.bcf.bcfstore as bcfstore
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class NewBcfProject(bpy.types.Operator):
|
||||
bl_idname = "bim.new_bcf_project"
|
||||
@@ -1256,8 +1253,8 @@ class ActivateBcfViewpoint(bpy.types.Operator):
|
||||
else:
|
||||
obj.data.show_background_images = False
|
||||
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||
assert (space := tool.Blender.get_view3d_space())
|
||||
space.region_3d.view_perspective = "CAMERA"
|
||||
|
||||
if self.file:
|
||||
self.set_viewpoint_components(viewpoint, context)
|
||||
|
||||
@@ -16,24 +16,24 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from . import bcfstore
|
||||
from bonsai.bim.prop import StrProperty
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from bcf.agnostic.extensions import get_extensions_attributes
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
import bpy
|
||||
from bcf.agnostic.extensions import get_extensions_attributes
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import StrProperty
|
||||
|
||||
from . import bcfstore
|
||||
|
||||
bcfviewpoints_enum = None
|
||||
|
||||
@@ -230,7 +230,7 @@ class BcfTopic(PropertyGroup):
|
||||
|
||||
|
||||
def get_related_topics(self: "BCFProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
||||
global RELATED_TOPICS_ENUM_ITEMS
|
||||
global RELATED_TOPICS_ENUM_ITEMS # ty: ignore[unresolved-global]
|
||||
props = self
|
||||
active_topic = props.active_topic
|
||||
active_related_topics = active_topic.related_topics.keys()
|
||||
|
||||
@@ -17,15 +17,18 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from . import bcfstore
|
||||
from bpy.types import Panel
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
from . import bcfstore
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.bcf.prop import BcfTopic, BCFProperties
|
||||
from bonsai.bim.module.bcf.prop import BCFProperties, BcfTopic
|
||||
|
||||
|
||||
class BIM_PT_bcf(Panel):
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, operator, prop
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddBoundary,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import gpu
|
||||
import bmesh
|
||||
import bonsai.tool as tool
|
||||
import gpu
|
||||
from bpy.types import SpaceView3D
|
||||
from mathutils import Vector
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class BoundaryDecorator:
|
||||
installed = None
|
||||
|
||||
@@ -16,34 +16,34 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
import logging
|
||||
import shapely
|
||||
import shapely.ops
|
||||
import mathutils
|
||||
import numpy as np
|
||||
import multiprocessing
|
||||
from math import acos, degrees, inf, pi, radians
|
||||
from typing import Optional, Union
|
||||
|
||||
import bmesh
|
||||
import bpy
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.boundary
|
||||
import ifcopenshell.api.root
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.ifcopenshell_wrapper as W
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.import_ifc as import_ifc
|
||||
from math import pi, inf, degrees, acos, radians
|
||||
from mathutils import Vector, Matrix
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.model.decorator import ProfileDecorator
|
||||
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.unit
|
||||
import mathutils
|
||||
import shapely
|
||||
import shapely.ops
|
||||
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||
import bonsai.core
|
||||
from mathutils import Matrix, Vector
|
||||
|
||||
import bonsai.bim.import_ifc as import_ifc
|
||||
import bonsai.core.geometry
|
||||
from typing import Union, Optional
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
|
||||
from bonsai.bim.module.model.decorator import ProfileDecorator
|
||||
|
||||
|
||||
def disable_editing_boundary_geometry(context):
|
||||
@@ -377,6 +377,8 @@ class EnableEditingBoundary(bpy.types.Operator):
|
||||
obj = tool.Ifc.get_object(entity)
|
||||
if entity and obj:
|
||||
setattr(bprops, blender_property, obj)
|
||||
bprops.physical_or_virtual = boundary.PhysicalOrVirtualBoundary or "NOTDEFINED"
|
||||
bprops.internal_or_external = boundary.InternalOrExternalBoundary or "NOTDEFINED"
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -392,6 +394,8 @@ class DisableEditingBoundary(bpy.types.Operator):
|
||||
bprops.is_editing = False
|
||||
for ifc_attribute, blender_property in EDITABLE_ATTRIBUTES.items():
|
||||
setattr(bprops, blender_property, None)
|
||||
bprops.physical_or_virtual = "NOTDEFINED"
|
||||
bprops.internal_or_external = "NOTDEFINED"
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -411,6 +415,8 @@ class EditBoundaryAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||
obj = getattr(bprops, blender_property, None)
|
||||
entity = tool.Ifc.get_entity(obj)
|
||||
attributes[blender_property] = entity
|
||||
attributes["physical_or_virtual"] = bprops.physical_or_virtual
|
||||
attributes["internal_or_external"] = bprops.internal_or_external
|
||||
ifcopenshell.api.boundary.edit_attributes(tool.Ifc.get(), entity=boundary, **attributes)
|
||||
bpy.ops.bim.disable_editing_boundary()
|
||||
return {"FINISHED"}
|
||||
@@ -702,6 +708,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
while True:
|
||||
tree.add_element(iterator.get_native())
|
||||
shape = iterator.get()
|
||||
assert isinstance(shape, W.TriangulationElement)
|
||||
shapes[shape.id] = {
|
||||
"verts": ifcopenshell.util.shape.get_vertices(shape.geometry),
|
||||
"faces": ifcopenshell.util.shape.get_faces(shape.geometry),
|
||||
|
||||
@@ -16,22 +16,19 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
from bonsai.bim.prop import ObjProperty
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
EnumProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import ObjProperty
|
||||
|
||||
|
||||
def space_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object) -> bool:
|
||||
entity = tool.Ifc.get_entity(object)
|
||||
@@ -54,12 +51,43 @@ def element_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object
|
||||
return False
|
||||
|
||||
|
||||
def get_internal_or_external_items(
|
||||
self: "BIMObjectBoundaryProperties", context: bpy.types.Context | None
|
||||
) -> list[tuple[str, str, str]]:
|
||||
items = [
|
||||
("INTERNAL", "Internal", ""),
|
||||
("EXTERNAL", "External", ""),
|
||||
]
|
||||
ifc = tool.Ifc.get()
|
||||
if not ifc or ifc.schema != "IFC2X3":
|
||||
items += [
|
||||
("EXTERNAL_EARTH", "External Earth", ""),
|
||||
("EXTERNAL_WATER", "External Water", ""),
|
||||
("EXTERNAL_FIRE", "External Fire", ""),
|
||||
]
|
||||
items.append(("NOTDEFINED", "Not Defined", ""))
|
||||
return items
|
||||
|
||||
|
||||
class BIMObjectBoundaryProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
relating_space: PointerProperty(name="RelatingSpace", type=bpy.types.Object, poll=space_filter)
|
||||
related_building_element: PointerProperty(name="RelatedBuildingElement", type=bpy.types.Object, poll=element_filter)
|
||||
parent_boundary: PointerProperty(name="ParentBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
corresponding_boundary: PointerProperty(name="CorrespondingBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
physical_or_virtual: EnumProperty(
|
||||
name="PhysicalOrVirtualBoundary",
|
||||
items=[
|
||||
("PHYSICAL", "Physical", ""),
|
||||
("VIRTUAL", "Virtual", ""),
|
||||
("NOTDEFINED", "Not Defined", ""),
|
||||
],
|
||||
default="NOTDEFINED",
|
||||
)
|
||||
internal_or_external: EnumProperty(
|
||||
name="InternalOrExternalBoundary",
|
||||
items=get_internal_or_external_items,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_editing: bool
|
||||
@@ -67,6 +95,8 @@ class BIMObjectBoundaryProperties(PropertyGroup):
|
||||
related_building_element: Union[bpy.types.Object, None]
|
||||
parent_boundary: Union[bpy.types.Object, None]
|
||||
corresponding_boundary: Union[bpy.types.Object, None]
|
||||
physical_or_virtual: str
|
||||
internal_or_external: str # values depend on schema: IFC2X3 omits EXTERNAL_EARTH/WATER/FIRE
|
||||
|
||||
|
||||
class BIMBoundaryProperties(PropertyGroup):
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
from bpy.types import Panel
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.boundary.data import SpaceBoundariesData
|
||||
|
||||
@@ -77,6 +77,10 @@ class BIM_PT_Boundary(Panel):
|
||||
self.draw_relation_editor(boundary, "RelatedBuildingElement", "related_building_element")
|
||||
self.draw_relation_editor(boundary, "ParentBoundary", "parent_boundary")
|
||||
self.draw_relation_editor(boundary, "CorrespondingBoundary", "corresponding_boundary")
|
||||
row = self.layout.row()
|
||||
row.prop(self.bprops, "physical_or_virtual")
|
||||
row = self.layout.row()
|
||||
row.prop(self.bprops, "internal_or_external")
|
||||
else:
|
||||
row = self.layout.row()
|
||||
row.operator("bim.enable_editing_boundary", icon="GREASEPENCIL", text="Edit")
|
||||
@@ -84,6 +88,8 @@ class BIM_PT_Boundary(Panel):
|
||||
self.draw_relation_data(boundary, "RelatedBuildingElement")
|
||||
self.draw_relation_data(boundary, "ParentBoundary")
|
||||
self.draw_relation_data(boundary, "CorrespondingBoundary")
|
||||
self.draw_enum_data(boundary, "PhysicalOrVirtualBoundary")
|
||||
self.draw_enum_data(boundary, "InternalOrExternalBoundary")
|
||||
if hasattr(boundary, "InnerBoundaries"):
|
||||
for i, inner_boundary in enumerate(getattr(boundary, "InnerBoundaries", ())):
|
||||
row = self.layout.row(align=True)
|
||||
@@ -110,6 +116,11 @@ class BIM_PT_Boundary(Panel):
|
||||
else:
|
||||
row.label(text="")
|
||||
|
||||
def draw_enum_data(self, boundary, ifc_attribute: str):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=ifc_attribute)
|
||||
row.label(text=getattr(boundary, ifc_attribute, "") or "")
|
||||
|
||||
def draw_relation_editor(self, boundary, ifc_attribute: str, blender_property: str):
|
||||
if hasattr(boundary, ifc_attribute):
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddBrick,
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.tool.brick import BrickStore
|
||||
|
||||
try:
|
||||
from rdflib import URIRef, BNode
|
||||
from rdflib import BNode, URIRef
|
||||
except:
|
||||
# See #1860
|
||||
print("Warning: brickschema not available.")
|
||||
@@ -62,8 +63,7 @@ class BrickschemaData:
|
||||
if namespace == "https://brickschema.org/schema/Brick":
|
||||
return []
|
||||
results = []
|
||||
query = BrickStore.graph.query(
|
||||
"""
|
||||
query = BrickStore.graph.query("""
|
||||
PREFIX brick: <https://brickschema.org/schema/Brick#>
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
||||
@@ -80,10 +80,7 @@ class BrickschemaData:
|
||||
}
|
||||
}
|
||||
GROUP BY ?object
|
||||
""".replace(
|
||||
"{uri}", uri
|
||||
)
|
||||
)
|
||||
""".replace("{uri}", uri))
|
||||
for row in query:
|
||||
predicate_uri = row.get("predicate")
|
||||
predicate_name = predicate_uri.toPython().split("#")[-1]
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.api
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.brick as core
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
import bonsai.bim.handler
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
import bonsai.core.brick as core
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.tool.brick import BrickStore
|
||||
|
||||
|
||||
@@ -16,24 +16,23 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.core.brick as core
|
||||
import bonsai.tool.brick as tool
|
||||
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
|
||||
from bonsai.bim.prop import StrProperty
|
||||
from bonsai.tool.brick import BrickStore
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
def update_active_brick_index(self, context):
|
||||
@@ -47,26 +46,26 @@ def get_libraries(self, context):
|
||||
|
||||
|
||||
def get_namespaces(self, context):
|
||||
global NAMESPACES_ENUM_ITEMS
|
||||
global NAMESPACES_ENUM_ITEMS # ty: ignore[unresolved-global]
|
||||
NAMESPACES_ENUM_ITEMS = [(uri, f"{alias}: {uri}", "") for alias, uri in BrickStore.namespaces]
|
||||
return NAMESPACES_ENUM_ITEMS
|
||||
|
||||
|
||||
def get_brick_entity_classes(self, context):
|
||||
global ENTITY_CLASSES_ENUM_ITEMS
|
||||
global ENTITY_CLASSES_ENUM_ITEMS # ty: ignore[unresolved-global]
|
||||
entity = self.brick_entity_create_type
|
||||
ENTITY_CLASSES_ENUM_ITEMS = [(uri, uri.split("#")[-1], "") for uri in BrickStore.entity_classes[entity]]
|
||||
return ENTITY_CLASSES_ENUM_ITEMS
|
||||
|
||||
|
||||
def get_brick_roots(self, context):
|
||||
global BRICK_ROOTS_ENUM_ITEMS
|
||||
global BRICK_ROOTS_ENUM_ITEMS # ty: ignore[unresolved-global]
|
||||
BRICK_ROOTS_ENUM_ITEMS = [(root, root, "") for root in BrickStore.root_classes]
|
||||
return BRICK_ROOTS_ENUM_ITEMS
|
||||
|
||||
|
||||
def get_brick_relations(self, context):
|
||||
global BRICK_RELATIONS_ENUM_ITEMS
|
||||
global BRICK_RELATIONS_ENUM_ITEMS # ty: ignore[unresolved-global]
|
||||
BRICK_RELATIONS_ENUM_ITEMS = [(uri, uri.split("#")[-1], "") for uri in BrickStore.relationships]
|
||||
for relation in BrickschemaData.data["active_relations"]:
|
||||
if relation["predicate_name"] == "label":
|
||||
|
||||
@@ -16,8 +16,18 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bonsai.tool as tool
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.brick.prop import Brick
|
||||
|
||||
from bonsai.bim.helper import prop_with_search
|
||||
from bonsai.bim.module.brick.data import BrickschemaData, BrickschemaReferencesData
|
||||
from bonsai.tool.brick import BrickStore
|
||||
@@ -273,7 +283,9 @@ class BIM_PT_brickschema_viewport(Panel):
|
||||
class BIM_UL_bricks(UIList):
|
||||
split_screen = False
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
def draw_item(
|
||||
self, context, layout: bpy.types.UILayout, data, item: Brick, icon, active_data, active_propname
|
||||
) -> None:
|
||||
if item:
|
||||
split = layout.split(factor=0.85, align=True)
|
||||
row = split.row()
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddBSDDProperties,
|
||||
|
||||
@@ -16,12 +16,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.classification
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
|
||||
def refresh():
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
import textwrap
|
||||
from typing import Any
|
||||
|
||||
import bpy
|
||||
import bsdd
|
||||
import bonsai.tool as tool
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.util.element
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.core import bsdd as core
|
||||
from typing import Any
|
||||
|
||||
|
||||
class LoadBSDDDictionaries(bpy.types.Operator):
|
||||
|
||||
@@ -16,23 +16,22 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.bsdd.data import BSDDData
|
||||
from bonsai.bim.module.classification.data import ClassificationsData
|
||||
from bonsai.bim.prop import Attribute, StrProperty
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import Union, TYPE_CHECKING, Literal
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
def get_active_dictionary(self: "BIMBSDDProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
|
||||
@@ -17,14 +17,22 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.bsdd.data import BSDDData
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.bsdd.data import BSDDData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDDictionary, BSDDClassification, BSDDProperty
|
||||
from bonsai.bim.module.bsdd.prop import (
|
||||
BIMBSDDProperties,
|
||||
BSDDClassification,
|
||||
BSDDDictionary,
|
||||
BSDDProperty,
|
||||
)
|
||||
|
||||
|
||||
class BIM_PT_bsdd(Panel):
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
from . import operator, prop, workspace
|
||||
|
||||
classes = (
|
||||
|
||||
@@ -16,17 +16,16 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import math
|
||||
import bmesh
|
||||
import mathutils
|
||||
import bpy_extras
|
||||
import bonsai.tool as tool
|
||||
from mathutils import Vector, Matrix
|
||||
from math import pi, radians, sin, cos, sqrt
|
||||
import ifcopenshell.util.unit
|
||||
from typing import Union
|
||||
from math import pi, sqrt
|
||||
|
||||
import bmesh
|
||||
import bpy
|
||||
import bpy_extras
|
||||
import mathutils
|
||||
from mathutils import Matrix, Vector
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
messages = {
|
||||
"SHARED_VERTEX": "Shared Vertex, no intersection possible",
|
||||
@@ -38,6 +37,7 @@ messages = {
|
||||
class CadTrimExtend(bpy.types.Operator):
|
||||
bl_idname = "bim.cad_trim_extend"
|
||||
bl_label = "CAD Trim / Extend"
|
||||
bl_description = "Extends/reduces element to 3D cursor"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -83,6 +83,7 @@ class CadTrimExtend(bpy.types.Operator):
|
||||
class CadMitre(bpy.types.Operator):
|
||||
bl_idname = "bim.cad_mitre"
|
||||
bl_label = "CAD Mitre"
|
||||
bl_description = "Joins two non-parallel paths at their intersection"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bpy.types import PropertyGroup
|
||||
from math import pi
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
|
||||
class BIMCadProperties(PropertyGroup):
|
||||
resolution: bpy.props.IntProperty(name="Arc Resolution", min=1, default=1)
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.type.prop as type_prop
|
||||
import ifcopenshell.util.unit
|
||||
from bpy.types import WorkSpaceTool
|
||||
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData
|
||||
from functools import partial
|
||||
|
||||
import bpy
|
||||
from bpy.types import WorkSpaceTool
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.model.data import RailingData, RoofData
|
||||
|
||||
|
||||
def load_custom_icons():
|
||||
global custom_icon_previews, display_mode
|
||||
@@ -106,23 +106,37 @@ class CadTool(WorkSpaceTool):
|
||||
)
|
||||
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Rectangle", "S_R", bpy.ops.bim.add_rectangle.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Circle", "S_C", bpy.ops.bim.add_ifccircle.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Rectangle", "S_R", bpy.ops.bim.add_rectangle.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "3-Point Arc", "S_V", bpy.ops.bim.set_arc_index.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Circle", "S_C", bpy.ops.bim.add_ifccircle.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Reset Vertex", "S_X", bpy.ops.bim.reset_vertex.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "3-Point Arc", "S_V", bpy.ops.bim.set_arc_index.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Reset Vertex", "S_X", bpy.ops.bim.reset_vertex.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
|
||||
elif (
|
||||
isinstance(data, tool.Geometry.TYPES_WITH_MESH_PROPERTIES)
|
||||
@@ -132,15 +146,21 @@ class CadTool(WorkSpaceTool):
|
||||
layout, "Edit Axis", "bim.edit_extrusion_axis", "bim.disable_editing_extrusion_axis", ui_context
|
||||
)
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.cad_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.cad_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
|
||||
else:
|
||||
if (
|
||||
@@ -168,19 +188,37 @@ class CadTool(WorkSpaceTool):
|
||||
add_layout_hotkey_operator(row, "Set Gable Roof Angle", "S_R", "Set Gable Roof Angle", ui_context)
|
||||
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "2-Point Arc", "S_C", bpy.ops.bim.cad_arc_from_2_points.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "3-Point Arc", "S_V", bpy.ops.bim.cad_arc_from_3_points.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row,
|
||||
"2-Point Arc",
|
||||
"S_C",
|
||||
bpy.ops.bim.cad_arc_from_2_points.__doc__.split("\n", 1)[1].strip(),
|
||||
ui_context,
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row,
|
||||
"3-Point Arc",
|
||||
"S_V",
|
||||
bpy.ops.bim.cad_arc_from_3_points.__doc__.split("\n", 1)[1].strip(),
|
||||
ui_context,
|
||||
)
|
||||
|
||||
|
||||
class CadHotkey(bpy.types.Operator):
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddClashSet,
|
||||
operator.AddClashSource,
|
||||
operator.ExecuteIfcClash,
|
||||
operator.ExportClashSets,
|
||||
operator.HideClash,
|
||||
operator.ImportClashSets,
|
||||
operator.LoadSmartGroupsForActiveClashSet,
|
||||
operator.RemoveClashSet,
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import ifcopenshell.util.element
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
|
||||
import blf
|
||||
import gpu
|
||||
import bmesh
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import SpaceView3D
|
||||
from mathutils import Vector
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
from mathutils import Vector
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class ClashDecorator:
|
||||
|
||||
@@ -16,22 +16,21 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
import tempfile
|
||||
import bmesh
|
||||
import logging
|
||||
import numpy as np
|
||||
import ifcopenshell
|
||||
import bonsai.tool as tool
|
||||
from pathlib import Path
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
import tempfile
|
||||
from math import radians
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
from mathutils import Matrix, Vector
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.clash.decorator import ClashDecorator
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
class ExportClashSets(bpy.types.Operator, ExportHelper):
|
||||
@@ -202,16 +201,10 @@ class ExecuteIfcClash(bpy.types.Operator, ExportHelper):
|
||||
"ALT+click to run a quick clash without selecting a file to save."
|
||||
)
|
||||
|
||||
filter_glob: bpy.props.StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
default="*.bcf;*.json", options={"HIDDEN"}
|
||||
)
|
||||
format: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Format", items=[(i, i, "") for i in ("bcf", "json")]
|
||||
)
|
||||
filepath: bpy.props.StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
subtype="FILE_PATH", options={"SKIP_SAVE"}
|
||||
)
|
||||
quick_clash: bpy.props.BoolProperty( # pyright: ignore[reportRedeclaration]
|
||||
filter_glob: bpy.props.StringProperty(default="*.bcf;*.json", options={"HIDDEN"})
|
||||
format: bpy.props.EnumProperty(name="Format", items=[(i, i, "") for i in ("bcf", "json")])
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH", options={"SKIP_SAVE"})
|
||||
quick_clash: bpy.props.BoolProperty(
|
||||
options={"SKIP_SAVE"},
|
||||
)
|
||||
|
||||
@@ -443,6 +436,25 @@ class SelectClash(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class HideClash(bpy.types.Operator):
|
||||
bl_idname = "bim.hide_clash"
|
||||
bl_label = "Hide Clash"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Hide the clash decorator"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if not ClashDecorator.is_installed:
|
||||
cls.poll_message_set("No clash selected.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
ClashDecorator.uninstall()
|
||||
tool.Blender.update_all_viewports(context)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SmartClashGroup(bpy.types.Operator):
|
||||
bl_idname = "bim.smart_clash_group"
|
||||
bl_label = "Smart Group Clashes"
|
||||
|
||||
@@ -16,32 +16,33 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import StrProperty, Attribute, BIMFilterGroup
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from ifcopenshell.geom.main import ClashType, CLASH_TYPE_ITEMS
|
||||
from bpy.types import PropertyGroup
|
||||
from ifcopenshell.geom.main import CLASH_TYPE_ITEMS, ClashType
|
||||
from mathutils import Vector
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import BIMFilterGroup, StrProperty
|
||||
|
||||
|
||||
class ClashSource(PropertyGroup):
|
||||
name: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
name: StringProperty(
|
||||
name="File",
|
||||
description="Absolute filepath to existing .ifc file to use as a clash source.",
|
||||
)
|
||||
filter_groups: CollectionProperty(type=BIMFilterGroup, name="Filter Groups") # pyright: ignore[reportRedeclaration]
|
||||
mode: EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
filter_groups: CollectionProperty(type=BIMFilterGroup, name="Filter Groups")
|
||||
mode: EnumProperty(
|
||||
items=[
|
||||
("a", "All Elements", "All elements will be used for clashing"),
|
||||
("i", "Include", "Only the selected elements are included for clashing"),
|
||||
@@ -61,7 +62,7 @@ class Clash(PropertyGroup):
|
||||
b_global_id: StringProperty(name="B")
|
||||
a_name: StringProperty(name="A Name")
|
||||
b_name: StringProperty(name="B Name")
|
||||
clash_type: EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
clash_type: EnumProperty(
|
||||
name="Clash Type",
|
||||
items=tuple((i, i, "") for i in CLASH_TYPE_ITEMS),
|
||||
)
|
||||
|
||||
@@ -17,15 +17,23 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.helper
|
||||
from bpy.types import Panel
|
||||
from bonsai.bim.module.clash.data import ClashData
|
||||
|
||||
from typing import TYPE_CHECKING, assert_never
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.clash.data import ClashData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.clash.prop import BIMClashProperties, ClashSet, SmartClashGroup, Clash
|
||||
from bonsai.bim.module.clash.prop import (
|
||||
BIMClashProperties,
|
||||
Clash,
|
||||
ClashSet,
|
||||
SmartClashGroup,
|
||||
)
|
||||
|
||||
|
||||
class BIM_PT_ifcclash(Panel):
|
||||
@@ -165,6 +173,7 @@ class BIM_PT_ifcclash(Panel):
|
||||
layout.template_list("BIM_UL_clashes", "", props.active_clash_set, "clashes", props, "active_clash_index")
|
||||
row = layout.row()
|
||||
row.operator("bim.select_clash")
|
||||
row.operator("bim.hide_clash", text="", icon="HIDE_ON")
|
||||
else:
|
||||
row.label(text="Clashes Are Not Loaded", icon="PIVOT_CURSOR")
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddClassification,
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Any, Literal, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.classification
|
||||
import ifcopenshell.util.date
|
||||
|
||||
import bonsai.tool as tool
|
||||
from typing import Any, Literal, Union
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
|
||||
@@ -104,6 +106,7 @@ class ReferencesData:
|
||||
if element:
|
||||
for reference in ifcopenshell.util.classification.get_references(element):
|
||||
data = reference.get_info()
|
||||
data["ifcClassificationReference"] = reference
|
||||
del data["ReferencedSource"]
|
||||
results.append(data)
|
||||
return results
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.api.classification
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.util.classification
|
||||
import ifcopenshell.util.element
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.helper
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
|
||||
@@ -257,7 +257,9 @@ class EnableEditingClassificationReference(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
props = tool.Classification.get_classification_reference_props()
|
||||
props.reference_attributes.clear()
|
||||
bonsai.bim.helper.import_attributes(tool.Ifc.get().by_id(self.reference), props.reference_attributes)
|
||||
ifc_reference = tool.Ifc.get().by_id(self.reference)
|
||||
bonsai.bim.helper.import_attributes(ifc_reference, props.reference_attributes)
|
||||
props.classification_system_name = ifc_reference.ReferencedSource.Name or ""
|
||||
props.active_reference_id = self.reference
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -324,9 +326,13 @@ class EditClassificationReference(bpy.types.Operator, tool.Ifc.Operator):
|
||||
props = tool.Classification.get_classification_reference_props()
|
||||
attributes = bonsai.bim.helper.export_attributes(props.reference_attributes)
|
||||
ifc_file = tool.Ifc.get()
|
||||
reference_entity = ifc_file.by_id(props.active_reference_id)
|
||||
referenced_source = reference_entity.ReferencedSource
|
||||
if props.classification_system_name:
|
||||
referenced_source.Name = props.classification_system_name
|
||||
ifcopenshell.api.classification.edit_reference(
|
||||
ifc_file,
|
||||
reference=ifc_file.by_id(props.active_reference_id),
|
||||
reference=reference_entity,
|
||||
attributes=attributes,
|
||||
)
|
||||
bpy.ops.bim.disable_editing_classification_reference()
|
||||
|
||||
@@ -16,23 +16,25 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import Attribute
|
||||
from bonsai.bim.module.classification.data import ClassificationsData, ObjectClassificationsData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.classification.data import (
|
||||
ClassificationsData,
|
||||
ObjectClassificationsData,
|
||||
)
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
def get_available_classifications(
|
||||
self: "BIMClassificationProperties", context: bpy.types.Context
|
||||
@@ -95,6 +97,7 @@ class BIMClassificationReferenceProperties(PropertyGroup):
|
||||
classifications: EnumProperty(items=get_classifications, name="Classifications")
|
||||
reference_attributes: CollectionProperty(name="Reference Attributes", type=Attribute)
|
||||
active_reference_id: IntProperty(name="Active Reference Id")
|
||||
classification_system_name: StringProperty(name="Classification System Name")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_adding: bool
|
||||
|
||||
@@ -17,22 +17,28 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.classification.prop as classification_prop
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.module.classification.data import (
|
||||
ClassificationsData,
|
||||
ObjectClassificationsData,
|
||||
MaterialClassificationsData,
|
||||
CostClassificationsData,
|
||||
ZoneClassificationsData,
|
||||
)
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.classification
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.classification.data import (
|
||||
ClassificationsData,
|
||||
CostClassificationsData,
|
||||
MaterialClassificationsData,
|
||||
ObjectClassificationsData,
|
||||
ZoneClassificationsData,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.classification.prop import BIMClassificationProperties, ClassificationReference
|
||||
from bonsai.bim.module.classification.prop import (
|
||||
BIMClassificationProperties,
|
||||
ClassificationReference,
|
||||
)
|
||||
|
||||
|
||||
class BIM_PT_classifications(Panel):
|
||||
@@ -152,7 +158,15 @@ class ReferenceUI:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="No References")
|
||||
|
||||
for reference in self.data.data["references"]:
|
||||
def get_classification_name(reference):
|
||||
classification_entity = ifcopenshell.util.classification.get_classification(
|
||||
reference["ifcClassificationReference"]
|
||||
)
|
||||
return classification_entity.Name if classification_entity else ""
|
||||
|
||||
sorted_references = sorted(self.data.data["references"], key=get_classification_name)
|
||||
|
||||
for reference in sorted_references:
|
||||
if self.props.active_reference_id == reference["id"]:
|
||||
self.draw_editable_ui()
|
||||
else:
|
||||
@@ -248,10 +262,20 @@ class ReferenceUI:
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_classification_reference", text="Save changes", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_classification_reference", text="", icon="CANCEL")
|
||||
row = self.layout.row()
|
||||
row.prop(self.props, "classification_system_name", text="Classification System Name")
|
||||
|
||||
bonsai.bim.helper.draw_attributes(self.props.reference_attributes, self.layout)
|
||||
|
||||
def draw_reference_ui(self, reference: dict[str, Any]) -> None:
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
classification_entity = ifcopenshell.util.classification.get_classification(
|
||||
reference["ifcClassificationReference"]
|
||||
)
|
||||
classification_name = classification_entity.Name if classification_entity else ""
|
||||
row.label(text=classification_name, icon="OUTLINER_COLLECTION")
|
||||
|
||||
if self.file.schema == "IFC2X3":
|
||||
name = reference["ItemReference"] or "No Identification"
|
||||
else:
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.LoadObjectives,
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from ifcopenshell.util.doc import get_entity_doc
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def refresh():
|
||||
ConstraintsData.is_loaded = False
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.constraint
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
def get_active_object(context: bpy.types.Context, obj_name: str) -> bpy.types.Object:
|
||||
|
||||
@@ -16,24 +16,20 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from ifcopenshell.util.doc import get_entity_doc
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import Attribute
|
||||
from bonsai.bim.module.constraint.data import ConstraintsData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
from bonsai.bim.module.constraint.data import ConstraintsData
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
def get_available_constraint_types(self, context):
|
||||
if not ConstraintsData.is_loaded:
|
||||
|
||||
@@ -17,14 +17,21 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.helper import draw_attributes
|
||||
from bonsai.bim.module.constraint.data import ConstraintsData, ObjectConstraintsData
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.helper import draw_attributes
|
||||
from bonsai.bim.module.constraint.data import ConstraintsData, ObjectConstraintsData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties, Constraint
|
||||
from bonsai.bim.module.constraint.prop import (
|
||||
BIMConstraintProperties,
|
||||
BIMObjectConstraintProperties,
|
||||
Constraint,
|
||||
)
|
||||
|
||||
|
||||
class BIM_PT_constraints(Panel):
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddContext,
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def refresh():
|
||||
ContextData.is_loaded = False
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
|
||||
import bonsai.core.context as core
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class AddContext(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
@@ -16,22 +16,18 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bonsai.bim.module.context.data import ContextData
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
from bonsai.bim.prop import Attribute
|
||||
|
||||
|
||||
class BIMContextProperties(PropertyGroup):
|
||||
contexts: EnumProperty(items=[("Model", "Model", ""), ("Plan", "Plan", "")], name="Contexts")
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.context.data import ContextData
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddCostColumn,
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from typing import Any, Union
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.cost
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
import bonsai.tool as tool
|
||||
from ifcopenshell.util.doc import get_entity_doc, get_predefined_type_doc
|
||||
from typing import Any, Union
|
||||
|
||||
|
||||
def refresh():
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
|
||||
# pyright: reportUnnecessaryTypeIgnoreComment=error
|
||||
|
||||
import bpy
|
||||
import textwrap
|
||||
import ifcopenshell.api.nest
|
||||
import bonsai.tool as tool
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.cost as core
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Literal, get_args
|
||||
|
||||
from typing import get_args, TYPE_CHECKING, Literal
|
||||
import bpy
|
||||
import ifcopenshell.api.nest
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
import bonsai.core.cost as core
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class AddCostSchedule(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -87,7 +87,7 @@ class CopyCostSchedule(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_label = "Copy Cost Schedule"
|
||||
bl_description = "Create a duplicate of the provided cost schedule."
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
cost_schedule: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
||||
cost_schedule: bpy.props.IntProperty()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
cost_schedule: int
|
||||
@@ -987,10 +987,10 @@ class ExportCostSchedulesToPDF(bpy.types.Operator, ExportHelper):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
try:
|
||||
import typst
|
||||
import typst # noqa: F401
|
||||
|
||||
return True
|
||||
except:
|
||||
except ModuleNotFoundError:
|
||||
cls.poll_message_set(
|
||||
"Typst not available.\nIt can be installed from Quality and\nControl -> Debug and using 'typst' with Pip Install.\n(Run Blender as Administrator)"
|
||||
)
|
||||
|
||||
@@ -16,25 +16,28 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.cost
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
FloatProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.classification.data import CostClassificationsData
|
||||
from bonsai.bim.module.cost.data import CostSchedulesData, CostItemRatesData, CostItemQuantitiesData
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
from bonsai.bim.module.cost.data import (
|
||||
CostItemQuantitiesData,
|
||||
CostItemRatesData,
|
||||
CostSchedulesData,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Literal, Union
|
||||
from bonsai.bim.prop import Attribute, StrProperty
|
||||
|
||||
|
||||
def get_schedule_of_rates(self: "BIMCostProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
|
||||
@@ -17,16 +17,20 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.bim.module.cost.prop as CostProp
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.module.cost.data import CostSchedulesData
|
||||
from typing import Any, TYPE_CHECKING
|
||||
from bonsai.bim.module.cost.data import CostItem, CostSchedulesData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.cost.prop import BIMCostProperties, CostItemQuantity
|
||||
from bonsai.bim.prop import StrProperty
|
||||
|
||||
|
||||
class BIM_PT_cost_schedules(Panel):
|
||||
@@ -395,8 +399,8 @@ class BIM_PT_cost_item_types(Panel):
|
||||
op = row2.operator("bim.calculate_cost_item_resource_value", text="", icon="DISC")
|
||||
op.cost_item = cost_item.ifc_definition_id
|
||||
|
||||
rtprops = context.scene.BIMResourceTreeProperties
|
||||
rprops = tool.Resource.get_resource_props()
|
||||
rtprops = rprops.tree
|
||||
if rtprops.resources and rprops.active_resource_index < len(rtprops.resources):
|
||||
if has_quantity_names:
|
||||
op = row2.operator("bim.assign_cost_item_quantity", text="", icon="PROPERTIES")
|
||||
@@ -658,9 +662,18 @@ class BIM_UL_cost_items_trait:
|
||||
split2.alignment = "LEFT"
|
||||
split2.label(text="Rate")
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
def draw_item(
|
||||
self,
|
||||
context,
|
||||
layout: bpy.types.UILayout,
|
||||
data: BIMCostProperties,
|
||||
item: CostProp.CostItem,
|
||||
icon,
|
||||
active_data,
|
||||
active_propname,
|
||||
) -> None:
|
||||
if item:
|
||||
self.props = tool.Cost.get_cost_props()
|
||||
self.props = data
|
||||
cost_item = CostSchedulesData.data["cost_items"][item.ifc_definition_id]
|
||||
row = layout.row(align=True)
|
||||
|
||||
@@ -691,7 +704,7 @@ class BIM_UL_cost_items_trait:
|
||||
|
||||
# TODO: reimplement "bim.copy_cost_item_values" somewhere with better UX
|
||||
|
||||
def draw_parent_operator(self, row, cost_item_id):
|
||||
def draw_parent_operator(self, row: bpy.types.UILayout, cost_item_id: int) -> None:
|
||||
if self.props.active_cost_item_id:
|
||||
if self.props.active_cost_item_id != cost_item_id:
|
||||
op = row.operator("bim.change_parent_cost_item", text="", icon="LINKED", emboss=False).new_parent = (
|
||||
@@ -700,7 +713,7 @@ class BIM_UL_cost_items_trait:
|
||||
else:
|
||||
row.label(text="", icon="BLANK1")
|
||||
|
||||
def draw_hierarchy(self, row, item):
|
||||
def draw_hierarchy(self, row: bpy.types.UILayout, item: CostProp.CostItem) -> None:
|
||||
for i in range(0, item.level_index):
|
||||
row.label(text="", icon="BLANK1")
|
||||
if item.has_children:
|
||||
@@ -746,7 +759,7 @@ class BIM_UL_cost_items_trait:
|
||||
else:
|
||||
row.label(text="-")
|
||||
|
||||
def draw_value_column(self, layout, cost_item):
|
||||
def draw_value_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
|
||||
if cost_item["TotalAppliedValue"]:
|
||||
text = "{0:,.2f}".format(cost_item["TotalAppliedValue"]).replace(",", " ")
|
||||
if cost_item["UnitBasisValueComponent"] not in [None, 1]:
|
||||
@@ -757,13 +770,13 @@ class BIM_UL_cost_items_trait:
|
||||
else:
|
||||
layout.label(text="-")
|
||||
|
||||
def draw_total_cost_column(self, layout, cost_item):
|
||||
def draw_total_cost_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
|
||||
format_numbers = "{0:,.2f}".format(cost_item["TotalCost"]).replace(",", " ")
|
||||
currency = CostSchedulesData.data["currency"]
|
||||
text = "{} {}".format(format_numbers, currency["name"]) if currency else format_numbers
|
||||
layout.label(text=text)
|
||||
|
||||
def draw_order_operator(self, row, ifc_definition_id, cost_item):
|
||||
def draw_order_operator(self, row: bpy.types.UILayout, ifc_definition_id: int, cost_item: CostItem) -> None:
|
||||
if cost_item["NestingIndex"] is not None:
|
||||
if cost_item["NestingIndex"] == 0:
|
||||
op = row.operator("bim.reorder_cost_item_nesting", icon="TRIA_DOWN", text="")
|
||||
@@ -790,12 +803,14 @@ class BIM_UL_cost_item_rates(BIM_UL_cost_items_trait, UIList):
|
||||
def draw_quantity_column(self, layout, cost_item):
|
||||
self.draw_uom_column(layout, cost_item)
|
||||
|
||||
def draw_total_cost_column(self, layout, cost_item):
|
||||
def draw_total_cost_column(self, layout: bpy.types.UILayout, cost_item: CostItem) -> None:
|
||||
pass # No such thing as a total cost in a schedule of rates
|
||||
|
||||
|
||||
class BIM_UL_cost_columns(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
def draw_item(
|
||||
self, context, layout: bpy.types.UILayout, data, item: StrProperty, icon, active_data, active_propname
|
||||
) -> None:
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
row.prop(item, "name", emboss=False, text="")
|
||||
@@ -803,9 +818,17 @@ class BIM_UL_cost_columns(UIList):
|
||||
|
||||
|
||||
class BIM_UL_cost_item_types(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
props = tool.Cost.get_cost_props()
|
||||
cost_item = props.cost_items[props.active_cost_item_index]
|
||||
def draw_item(
|
||||
self,
|
||||
context,
|
||||
layout: bpy.types.UILayout,
|
||||
data: BIMCostProperties,
|
||||
item: CostProp.CostItemType,
|
||||
icon,
|
||||
active_data,
|
||||
active_propname,
|
||||
) -> None:
|
||||
cost_item = data.cost_items[data.active_cost_item_index]
|
||||
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
@@ -841,7 +864,16 @@ class BIM_UL_cost_item_quantities(UIList):
|
||||
|
||||
|
||||
class BIM_UL_product_cost_items(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
def draw_item(
|
||||
self,
|
||||
context,
|
||||
layout: bpy.types.UILayout,
|
||||
data,
|
||||
item: CostItemQuantity,
|
||||
icon,
|
||||
active_data,
|
||||
active_propname,
|
||||
) -> None:
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
op = row.operator("bim.highlight_product_cost_item", text="", icon="STYLUS_PRESSURE")
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
from . import prop, workspace
|
||||
|
||||
classes = (
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
class BIMCoveringProperties(PropertyGroup):
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
|
||||
|
||||
import os
|
||||
from functools import partial
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
from bpy.types import WorkSpaceTool
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.helper import prop_with_search
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bpy.types import WorkSpaceTool
|
||||
from functools import partial
|
||||
|
||||
|
||||
class CoveringTool(WorkSpaceTool):
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
prop.CoveToolProject,
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import ifcopenshell
|
||||
from math import atan2, degrees
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.element
|
||||
|
||||
import bonsai.tool as tool
|
||||
from math import degrees, atan2
|
||||
|
||||
from .api import Api
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class CoveToolProject(bpy.types.PropertyGroup):
|
||||
run_set: bpy.props.StringProperty(name="Run Set")
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy.types
|
||||
import bonsai.tool as tool
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy.types
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.covetool.prop import CoveToolProperties, CoveToolProject
|
||||
from bonsai.bim.module.covetool.prop import CoveToolProject, CoveToolProperties
|
||||
|
||||
|
||||
class BIM_PT_covetool(bpy.types.Panel):
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.AddCsvAttribute,
|
||||
|
||||
@@ -17,20 +17,19 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import bpy
|
||||
|
||||
import json
|
||||
import ifccsv
|
||||
import logging
|
||||
import tempfile
|
||||
from collections import Counter
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.selector
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.drawing.scheduler as scheduler
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
import bonsai.bim.module.drawing.scheduler as scheduler
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.handler import refresh_ui_data
|
||||
from typing import TYPE_CHECKING
|
||||
from collections import Counter
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import pandas as pd
|
||||
|
||||
@@ -16,21 +16,19 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bonsai.bim.prop import StrProperty, BIMFilterGroup
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
from bonsai.bim.prop import BIMFilterGroup
|
||||
|
||||
|
||||
class CsvAttribute(PropertyGroup):
|
||||
name: StringProperty(name="Query", default="class")
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from bpy.types import Panel
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel
|
||||
from bonsai.bim.module.search.data import SearchData
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.ChangeLogLevel,
|
||||
|
||||
@@ -16,34 +16,35 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import bpy
|
||||
import time
|
||||
import random
|
||||
import logging
|
||||
import subprocess
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, Literal, Union, assert_never, get_args
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.pset
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.ifcopenshell_wrapper as W
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.unit
|
||||
import bonsai.tool as tool
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
import bonsai.bim.handler
|
||||
import bonsai.bim.import_ifc as import_ifc
|
||||
import bonsai.core.debug as core
|
||||
import bonsai.core.profile
|
||||
import bonsai.core.type
|
||||
import bonsai.bim.handler
|
||||
import bonsai.bim.import_ifc as import_ifc
|
||||
from collections import defaultdict
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
from pathlib import Path
|
||||
from bonsai import get_debug_info, format_debug_info
|
||||
import bonsai.tool as tool
|
||||
from bonsai import format_debug_info, get_debug_info
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from typing import get_args, Union, Any, TYPE_CHECKING, Literal, get_args, assert_never
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.prop import Attribute
|
||||
@@ -259,14 +260,14 @@ class CreateAllShapes(bpy.types.Operator):
|
||||
)
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
geometry_library: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
geometry_library: bpy.props.EnumProperty(
|
||||
name="Geometry Library",
|
||||
description="Geometry library to use for testing shape creation.",
|
||||
items=[(i, i, "") for i in get_args(ifcopenshell.geom.GEOMETRY_LIBRARY)],
|
||||
# By default use the same library as used for importing ifc project.
|
||||
default="hybrid-cgal-simple-opencascade",
|
||||
)
|
||||
custom_geometry_library: bpy.props.StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
custom_geometry_library: bpy.props.StringProperty(
|
||||
name="Custom Geometry Library",
|
||||
description="Provide a custom geometry library name, will override the 'geometry library' property.",
|
||||
)
|
||||
@@ -780,7 +781,7 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_label = "Purge Unused Objects"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
object_type: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
object_type: bpy.props.EnumProperty(
|
||||
name="Object Type",
|
||||
items=((s, s.capitalize(), "") for s in get_args(tool.Debug.PurgeMergeObjectType)),
|
||||
)
|
||||
@@ -826,7 +827,7 @@ class MergeIdenticalObjects(bpy.types.Operator, tool.Ifc.Operator):
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
object_type: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
object_type: bpy.props.EnumProperty(
|
||||
name="Object Type",
|
||||
items=((s, s.capitalize(), "") for s in get_args(tool.Debug.PurgeMergeObjectType)),
|
||||
)
|
||||
@@ -1072,7 +1073,7 @@ class ChangeLogLevel(bpy.types.Operator):
|
||||
bl_options = {"REGISTER"}
|
||||
bl_description = "Change general log level across all Python code in Blender"
|
||||
|
||||
log_level: bpy.props.EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
log_level: bpy.props.EnumProperty(
|
||||
name="Log Level",
|
||||
items=[(i, i, "") for i in get_args(LogLevelType)],
|
||||
default="WARNING",
|
||||
|
||||
@@ -16,21 +16,19 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Literal, get_args
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
CollectionProperty,
|
||||
EnumProperty,
|
||||
IntProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
from bonsai.bim.prop import Attribute, StrProperty
|
||||
|
||||
DisplayType = Literal["BOUNDS", "WIRE", "SOLID", "TEXTURED"]
|
||||
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
class BIM_PT_debug(Panel):
|
||||
bl_label = "Debug"
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
# system when the add-on loads. This is where it happens.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
# You'll need to provide a list of every one of your classes here. If you forget
|
||||
# to specify your class, it won't load and you won't be able to use that
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
# "Operators", since they correlate to a single user operation.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
|
||||
import bonsai.core.demo as core
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
# Each button correlates to a class like the one below. In this case, we're
|
||||
|
||||
@@ -32,21 +32,13 @@
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import bpy
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
# Properties have many different data types. We won't use all of them in this
|
||||
# demo module, but this is a list for your reference.
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
EnumProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
StringProperty,
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
|
||||
# All properties must belong in a property group. Usually, you'd have a group
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
# panels, buttons, labels, and input fields are laid out.
|
||||
|
||||
import bpy
|
||||
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.module.demo.data import DemoData
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
from . import operator, prop, ui
|
||||
|
||||
classes = (
|
||||
operator.ExecuteIfcDiff,
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import json
|
||||
|
||||
import bpy
|
||||
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
|
||||
@@ -16,15 +16,17 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import logging
|
||||
|
||||
import bpy
|
||||
import ifcdiff
|
||||
import ifcopenshell
|
||||
from bpy_extras.io_utils import ExportHelper, ImportHelper
|
||||
|
||||
import bonsai.bim.handler
|
||||
import bonsai.bim.import_ifc
|
||||
import bonsai.tool as tool
|
||||
from bpy_extras.io_utils import ImportHelper, ExportHelper
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
|
||||
@@ -96,8 +98,8 @@ class VisualiseDiff(bpy.types.Operator):
|
||||
obj.color = (0.0, 1.0, 0.0, 1.0)
|
||||
elif global_id in diff["changed"]:
|
||||
obj.color = (0.0, 0.0, 1.0, 1.0)
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
area.spaces[0].shading.color_type = "OBJECT"
|
||||
assert (space := tool.Blender.get_view3d_space())
|
||||
space.shading.color_type = "OBJECT"
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user