mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Construction Types Browser - Multipreview now runs smoothly (#2463)
* Construction types multipreview now runs smoothly * Minor fix * Minor fix
This commit is contained in:
committed by
GitHub
parent
e4e9db0b3e
commit
e9a063ccbd
@@ -59,6 +59,7 @@ classes = (
|
||||
slab.SetArcIndex,
|
||||
prop.ConstrTypeInfo,
|
||||
prop.ConstrClassInfo,
|
||||
prop.ConstrBrowserState,
|
||||
prop.BIMModelProperties,
|
||||
ui.BIM_PT_authoring,
|
||||
ui.DisplayConstrTypesUI,
|
||||
|
||||
@@ -31,6 +31,7 @@ import blenderbim.core.geometry
|
||||
from . import wall, slab, profile, mep
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
from blenderbim.bim.module.model.prop import store_cursor_position
|
||||
from ifcopenshell.api.pset.data import Data as PsetData
|
||||
from mathutils import Vector, Matrix
|
||||
from bpy_extras.object_utils import AddObjectHelper
|
||||
@@ -218,33 +219,37 @@ class ReinvokeOperator(bpy.types.Operator):
|
||||
bl_options = {"REGISTER"}
|
||||
bl_description = "Reinvoke a popup operator"
|
||||
operator: bpy.props.StringProperty()
|
||||
mouse_x: bpy.props.IntProperty()
|
||||
mouse_y: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
event_mouse_x, event_mouse_y = event.mouse_x, event.mouse_y
|
||||
window_mouse_x, window_mouse_y = self.mouse_x, self.mouse_y
|
||||
if (event_mouse_x, event_mouse_y) == (10, 10):
|
||||
return {"FINISHED"}
|
||||
browser_state = context.scene.BIMModelProperties.constr_browser_state
|
||||
store_cursor_position(context, event, window=False)
|
||||
cursor_x, cursor_y = browser_state.cursor_x, browser_state.cursor_y
|
||||
window_x, window_y = browser_state.window_x, browser_state.window_y
|
||||
window = context.window
|
||||
window.cursor_set("WAIT")
|
||||
window.cursor_warp(10, 10)
|
||||
run_operator = self.run_operator
|
||||
operator = self.operator
|
||||
self.move_cursor_away(context, window)
|
||||
|
||||
def move_cursor_to_window():
|
||||
window.cursor_warp(window_x, window_y)
|
||||
|
||||
def run_operator(operator, *args, **kwargs):
|
||||
reduce(lambda x, arg: getattr(x, arg), operator.split("."), bpy.ops)(*args, **kwargs)
|
||||
|
||||
def reinvoke():
|
||||
window.cursor_warp(event_mouse_x, event_mouse_y)
|
||||
kwargs = {}
|
||||
if (window_mouse_x, window_mouse_y) != (0, 0):
|
||||
kwargs.update({"mouse_x": window_mouse_x, "mouse_y": window_mouse_y})
|
||||
run_operator(operator, "INVOKE_DEFAULT", **kwargs)
|
||||
run_operator(operator, "INVOKE_DEFAULT", reinvoked=True)
|
||||
window.cursor_warp(cursor_x, cursor_y)
|
||||
|
||||
bpy.app.timers.register(reinvoke)
|
||||
bpy.app.timers.register(move_cursor_to_window, first_interval=browser_state.update_delay)
|
||||
bpy.app.timers.register(reinvoke, first_interval=3*browser_state.update_delay)
|
||||
return {"FINISHED"}
|
||||
|
||||
def move_cursor_away(self, context, window): # closes current popup
|
||||
browser_state = context.scene.BIMModelProperties.constr_browser_state
|
||||
window.cursor_warp(browser_state.far_away_x, browser_state.far_away_y)
|
||||
|
||||
@staticmethod
|
||||
def run_operator(operator, *args, **kwargs):
|
||||
reduce(lambda x, arg: getattr(x, arg), operator.split("."), bpy.ops)(*args, **kwargs)
|
||||
|
||||
@@ -41,6 +41,14 @@ def get_relating_type_browser(self, context):
|
||||
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
|
||||
@@ -129,6 +137,17 @@ class ConstrClassInfo(PropertyGroup):
|
||||
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(
|
||||
@@ -151,6 +170,7 @@ class BIMModelProperties(PropertyGroup):
|
||||
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=(
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import bpy
|
||||
from bpy.types import Panel, Operator, Menu
|
||||
from blenderbim.bim.module.model.data import AuthoringData
|
||||
from blenderbim.bim.module.model.prop import store_cursor_position
|
||||
from blenderbim.bim.helper import prop_with_search, close_operator_panel
|
||||
|
||||
|
||||
@@ -41,20 +42,34 @@ class DisplayConstrTypesUI(Operator):
|
||||
bl_label = "Browse Construction Types"
|
||||
bl_options = {"REGISTER"}
|
||||
bl_description = "Display all available Construction Types to add new instances"
|
||||
mouse_x: bpy.props.IntProperty(default=0)
|
||||
mouse_y: bpy.props.IntProperty(default=0)
|
||||
reinvoked: bpy.props.BoolProperty(default=False)
|
||||
|
||||
def execute(self, context):
|
||||
return {"FINISHED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
if (self.mouse_x, self.mouse_y) == (0, 0):
|
||||
self.mouse_x, self.mouse_y = context.window.x, context.window.y
|
||||
store_cursor_position(context, event, window=not self.reinvoked)
|
||||
return context.window_manager.invoke_popup(self, width=550)
|
||||
|
||||
def reinvoke(self, context):
|
||||
browser_state = context.scene.BIMModelProperties.constr_browser_state
|
||||
|
||||
def set_updating_transaction():
|
||||
browser_state.updating = True
|
||||
|
||||
def run_operator():
|
||||
bpy.ops.bim.reinvoke_operator(
|
||||
"INVOKE_DEFAULT", operator="bim.display_constr_types_ui"
|
||||
)
|
||||
browser_state.updating = False
|
||||
|
||||
if not browser_state.updating:
|
||||
bpy.app.timers.register(set_updating_transaction)
|
||||
bpy.app.timers.register(run_operator, first_interval=browser_state.update_delay)
|
||||
|
||||
def draw(self, context):
|
||||
bpy.context.window.cursor_set("DEFAULT")
|
||||
props = context.scene.BIMModelProperties
|
||||
|
||||
if AuthoringData.data["ifc_classes"]:
|
||||
row = self.layout.row()
|
||||
row.label(text="", icon="FILE_VOLUME")
|
||||
@@ -65,6 +80,7 @@ class DisplayConstrTypesUI(Operator):
|
||||
flow = self.layout.grid_flow(row_major=True, columns=num_cols, even_columns=True, even_rows=True, align=True)
|
||||
relating_types = AuthoringData.relating_types_browser()
|
||||
num_types = len(relating_types)
|
||||
|
||||
for idx, (relating_type_id, name, desc) in enumerate(relating_types):
|
||||
outer_col = flow.column()
|
||||
box = outer_col.box()
|
||||
@@ -72,31 +88,32 @@ class DisplayConstrTypesUI(Operator):
|
||||
row.label(text=name, icon="FILE_3D")
|
||||
row.alignment = "CENTER"
|
||||
row = box.row()
|
||||
|
||||
if ifc_class in props.constr_classes:
|
||||
constr_class_info = props.constr_classes[ifc_class]
|
||||
constr_types_info = constr_class_info.constr_types
|
||||
|
||||
if relating_type_id in constr_types_info:
|
||||
icon_id = constr_types_info[relating_type_id].icon_id
|
||||
row.template_icon(icon_value=icon_id, scale=6.0)
|
||||
else:
|
||||
mouse_x, mouse_y = self.mouse_x, self.mouse_y
|
||||
|
||||
def run_operator():
|
||||
bpy.ops.bim.reinvoke_operator(
|
||||
"INVOKE_DEFAULT", operator="bim.display_constr_types_ui", mouse_x=mouse_x, mouse_y=mouse_y
|
||||
)
|
||||
bpy.app.timers.register(run_operator)
|
||||
self.reinvoke(context)
|
||||
return
|
||||
|
||||
row = box.row()
|
||||
op = row.operator("bim.add_constr_type_instance", icon="ADD")
|
||||
op.from_invoke = True
|
||||
op.ifc_class = ifc_class
|
||||
|
||||
if relating_type_id.isnumeric():
|
||||
op.relating_type_id = int(relating_type_id)
|
||||
|
||||
last_row_cols = num_types % num_cols
|
||||
|
||||
if last_row_cols != 0:
|
||||
for _ in range(num_cols - last_row_cols):
|
||||
flow.column()
|
||||
|
||||
row = self.layout.row()
|
||||
row.alignment = "RIGHT"
|
||||
row.operator("bim.help_relating_types", text="", icon="QUESTION")
|
||||
|
||||
Reference in New Issue
Block a user