mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 05:46:51 +00:00
204 lines
8.5 KiB
Python
204 lines
8.5 KiB
Python
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
|
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
|
#
|
|
# This file is part of BlenderBIM Add-on.
|
|
#
|
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import bpy
|
|
from blenderbim.bim.prop import ObjProperty
|
|
from blenderbim.bim.module.model.data import AuthoringData
|
|
from blenderbim.bim.module.model.root import ConstrTypeEntityNotFound
|
|
from bpy.types import PropertyGroup
|
|
|
|
|
|
def get_ifc_class(self, context):
|
|
if not AuthoringData.is_loaded:
|
|
AuthoringData.load()
|
|
return AuthoringData.data["ifc_classes"]
|
|
|
|
|
|
def get_relating_type(self, context):
|
|
if not AuthoringData.is_loaded:
|
|
AuthoringData.load()
|
|
return AuthoringData.data["relating_types_ids"]
|
|
|
|
|
|
def get_relating_type_browser(self, context):
|
|
if not AuthoringData.is_loaded:
|
|
AuthoringData.load()
|
|
return AuthoringData.data["relating_types_ids_browser"]
|
|
|
|
|
|
def store_cursor_position(context, event, cursor=True, window=True):
|
|
browser_state = context.scene.BIMModelProperties.constr_browser_state
|
|
if cursor:
|
|
browser_state.cursor_x, browser_state.cursor_y = event.mouse_x, event.mouse_y
|
|
if window:
|
|
browser_state.window_x, browser_state.window_y = event.mouse_x, event.mouse_y
|
|
|
|
|
|
def update_icon_id(self, context, browser=False):
|
|
if context == "lost_context" or (context.region is not None and context.region.type != "TOOL_HEADER"):
|
|
ifc_class = self.ifc_class_browser if browser else self.ifc_class
|
|
relating_type_id = self.relating_type_id_browser if browser else self.relating_type_id
|
|
# relating_type = AuthoringData.relating_type_name_by_id(ifc_class, relating_type_id)
|
|
|
|
if ifc_class not in self.constr_classes or relating_type_id not in self.constr_classes[ifc_class].constr_types:
|
|
try:
|
|
AuthoringData.assetize_relating_type_from_selection(browser=browser)
|
|
except ConstrTypeEntityNotFound:
|
|
return
|
|
|
|
def set_icon(update_interval_seconds=1e-4):
|
|
if (ifc_class not in self.constr_classes
|
|
or relating_type_id not in self.constr_classes[ifc_class].constr_types):
|
|
return update_interval_seconds
|
|
else:
|
|
self.icon_id = self.constr_classes[ifc_class].constr_types[relating_type_id].icon_id
|
|
|
|
bpy.app.timers.register(set_icon)
|
|
|
|
|
|
def update_ifc_class(self, context):
|
|
AuthoringData.data["relating_types_ids"] = AuthoringData.relating_types()
|
|
AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail()
|
|
|
|
|
|
def update_ifc_class_browser(self, context):
|
|
if context.region is not None and context.region.type != "TOOL_HEADER":
|
|
AuthoringData.load_ifc_classes()
|
|
AuthoringData.load_relating_types_browser()
|
|
if self.updating:
|
|
return
|
|
ifc_class = self.ifc_class_browser
|
|
constr_class_info = AuthoringData.constr_class_info(ifc_class)
|
|
|
|
if constr_class_info is None or not constr_class_info.fully_loaded:
|
|
AuthoringData.assetize_constr_class(ifc_class)
|
|
|
|
|
|
def update_relating_type(self, context):
|
|
AuthoringData.load_relating_types()
|
|
AuthoringData.data["type_thumbnail"] = AuthoringData.type_thumbnail()
|
|
|
|
|
|
def update_relating_type_browser(self, context):
|
|
AuthoringData.load_relating_types_browser()
|
|
if not self.updating:
|
|
update_icon_id(self, context, browser=True)
|
|
|
|
|
|
def update_relating_type_by_name(self, context):
|
|
AuthoringData.load_relating_types()
|
|
relating_type_id = AuthoringData.relating_type_id_by_name(self.ifc_class, self.relating_type)
|
|
if relating_type_id is not None:
|
|
self.relating_type_id = relating_type_id
|
|
|
|
|
|
def get_constr_class_info(props, ifc_class):
|
|
return props.constr_classes[ifc_class] if ifc_class in props.constr_classes else None
|
|
|
|
|
|
def update_preview_multiple(self, context):
|
|
if context.region is not None and context.region.type != "TOOL_HEADER":
|
|
if self.preview_multiple_constr_types:
|
|
ifc_class = self.ifc_class
|
|
constr_class_info = get_constr_class_info(self, ifc_class)
|
|
if constr_class_info is None or not constr_class_info.fully_loaded:
|
|
AuthoringData.assetize_constr_class(ifc_class)
|
|
else:
|
|
update_relating_type(self, context)
|
|
|
|
|
|
class ConstrTypeInfo(PropertyGroup):
|
|
name: bpy.props.StringProperty(name="Construction type ID")
|
|
icon_id: bpy.props.IntProperty(name="Icon ID")
|
|
object: bpy.props.PointerProperty(name="Object", type=bpy.types.Object)
|
|
|
|
|
|
class ConstrClassInfo(PropertyGroup):
|
|
name: bpy.props.StringProperty(name="Construction class")
|
|
constr_types: bpy.props.CollectionProperty(type=ConstrTypeInfo)
|
|
fully_loaded: bpy.props.BoolProperty(default=False)
|
|
|
|
|
|
class ConstrBrowserState(PropertyGroup):
|
|
cursor_x: bpy.props.IntProperty()
|
|
cursor_y: bpy.props.IntProperty()
|
|
window_x: bpy.props.IntProperty()
|
|
window_y: bpy.props.IntProperty()
|
|
far_away_x: bpy.props.IntProperty(default=10) # lower left corner to temporarily warp the mouse
|
|
far_away_y: bpy.props.IntProperty(default=10) # useful to close popup operators
|
|
updating: bpy.props.BoolProperty()
|
|
update_delay: bpy.props.FloatProperty(default=3e-2)
|
|
|
|
|
|
class BIMModelProperties(PropertyGroup):
|
|
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
|
ifc_class_browser: bpy.props.EnumProperty(
|
|
items=get_ifc_class, name="Construction Class", update=update_ifc_class_browser
|
|
)
|
|
relating_type: bpy.props.StringProperty(update=update_relating_type_by_name)
|
|
relating_type_id: bpy.props.EnumProperty(
|
|
items=get_relating_type, name="Construction Type", update=update_relating_type
|
|
)
|
|
relating_type_id_browser: bpy.props.EnumProperty(
|
|
items=get_relating_type_browser, name="Construction Type", update=update_relating_type_browser
|
|
)
|
|
icon_id: bpy.props.IntProperty()
|
|
preview_multiple_constr_types: bpy.props.BoolProperty(default=False, update=update_preview_multiple)
|
|
updating: bpy.props.BoolProperty(default=False)
|
|
occurrence_name_style: bpy.props.EnumProperty(
|
|
items=[("CLASS", "By Class", ""), ("TYPE", "By Type", ""), ("CUSTOM", "Custom", "")],
|
|
name="Occurrence Name Style",
|
|
)
|
|
occurrence_name_function: bpy.props.StringProperty(name="Occurrence Name Function")
|
|
getter_enum = {"ifc_class": get_ifc_class, "relating_type": get_relating_type}
|
|
constr_classes: bpy.props.CollectionProperty(type=ConstrClassInfo)
|
|
constr_browser_state: bpy.props.PointerProperty(type=ConstrBrowserState)
|
|
extrusion_depth: bpy.props.FloatProperty(default=42.0)
|
|
cardinal_point: bpy.props.EnumProperty(
|
|
items=(
|
|
# TODO: complain to buildingSMART
|
|
("1", "bottom left", ""),
|
|
("2", "bottom centre", ""),
|
|
("3", "bottom right", ""),
|
|
("4", "mid-depth left", ""),
|
|
("5", "mid-depth centre", ""),
|
|
("6", "mid-depth right", ""),
|
|
("7", "top left", ""),
|
|
("8", "top centre", ""),
|
|
("9", "top right", ""),
|
|
("10", "geometric centroid", ""),
|
|
("11", "bottom in line with the geometric centroid", ""),
|
|
("12", "left in line with the geometric centroid", ""),
|
|
("13", "right in line with the geometric centroid", ""),
|
|
("14", "top in line with the geometric centroid", ""),
|
|
("15", "shear centre", ""),
|
|
("16", "bottom in line with the shear centre", ""),
|
|
("17", "left in line with the shear centre", ""),
|
|
("18", "right in line with the shear centre", ""),
|
|
("19", "top in line with the shear centre", ""),
|
|
),
|
|
name="Cardinal Point",
|
|
default="5",
|
|
)
|
|
length: bpy.props.FloatProperty(default=42.0)
|
|
openings: bpy.props.CollectionProperty(type=ObjProperty)
|
|
x: bpy.props.FloatProperty(name="X", default=0.5)
|
|
y: bpy.props.FloatProperty(name="Y", default=0.5)
|
|
z: bpy.props.FloatProperty(name="Z", default=0.5)
|
|
rl: bpy.props.FloatProperty(name="RL", default=1)
|