mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
See #5888. Fix bug where polyline tools weren't part of the undo system.
This commit is contained in:
@@ -407,7 +407,12 @@ class IfcStore:
|
||||
obj.BIMObjectProperties.ifc_definition_id = 0
|
||||
|
||||
@staticmethod
|
||||
def execute_ifc_operator(operator: tool.Ifc.Operator, context: bpy.types.Context, is_invoke=False) -> set[str]:
|
||||
def execute_ifc_operator(
|
||||
operator: tool.Ifc.Operator,
|
||||
context: bpy.types.Context,
|
||||
event=None,
|
||||
method: Literal["EXECUTE", "INVOKE", "MODAL"] = "EXECUTE",
|
||||
) -> set[str]:
|
||||
bonsai.last_actions.append({"type": "operator", "name": operator.bl_idname})
|
||||
bpy.context.scene.BIMProperties.is_dirty = True
|
||||
is_top_level_operator = not bool(IfcStore.current_transaction)
|
||||
@@ -436,10 +441,12 @@ class IfcStore:
|
||||
bonsai.bim.handler.refresh_ui_data()
|
||||
|
||||
try:
|
||||
if is_invoke:
|
||||
result = getattr(operator, "_invoke")(context, None)
|
||||
else:
|
||||
if method == "EXECUTE":
|
||||
result = getattr(operator, "_execute")(context)
|
||||
elif method == "INVOKE":
|
||||
result = getattr(operator, "_invoke")(context, event)
|
||||
elif method == "MODAL":
|
||||
result = getattr(operator, "_modal")(context, event)
|
||||
except:
|
||||
bonsai.last_error = traceback.format_exc()
|
||||
# Try to ensure undo will work since Blender undo does work in case of errors.
|
||||
|
||||
@@ -1913,7 +1913,7 @@ class OverrideModeSetEdit(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
if not tool.Ifc.get():
|
||||
@@ -2089,7 +2089,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
|
||||
should_save: bpy.props.BoolProperty(name="Should Save", default=True)
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str]:
|
||||
if not tool.Ifc.get():
|
||||
|
||||
@@ -154,7 +154,7 @@ class AddDefaultType(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bpy.ops.bim.add_element()
|
||||
|
||||
|
||||
class AddOccurrence(bpy.types.Operator, PolylineOperator):
|
||||
class AddOccurrence(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_occurrence"
|
||||
bl_label = "Add Occurrence"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
@@ -199,6 +199,9 @@ class AddOccurrence(bpy.types.Operator, PolylineOperator):
|
||||
snap_obj.select_set(False)
|
||||
|
||||
def modal(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="MODAL")
|
||||
|
||||
def _modal(self, context, event):
|
||||
# Ensure state of BIM tool props is valid
|
||||
props = tool.Model.get_model_props()
|
||||
relating_type_id = tool.Blender.get_enum_safe(props, "relating_type_id")
|
||||
@@ -251,6 +254,9 @@ class AddOccurrence(bpy.types.Operator, PolylineOperator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
super().invoke(context, event)
|
||||
ProductDecorator.install(context)
|
||||
self.tool_state.use_default_container = True
|
||||
|
||||
@@ -32,9 +32,9 @@ import bonsai.core.type
|
||||
import bonsai.core.geometry
|
||||
import bonsai.core.material
|
||||
import bonsai.core.root
|
||||
from math import pi, degrees, inf, atan2
|
||||
from mathutils import Vector, Matrix, Quaternion
|
||||
from bonsai.bim.module.geometry.helper import Helper
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from math import pi, degrees, atan2
|
||||
from mathutils import Vector, Matrix
|
||||
from bonsai.bim.module.model.wall import DumbWallRecalculator
|
||||
from bonsai.bim.module.model.decorator import ProfileDecorator, PolylineDecorator, ProductDecorator
|
||||
from bonsai.bim.module.model.polyline import PolylineOperator
|
||||
@@ -1109,7 +1109,7 @@ class EditExtrusionAxis(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
|
||||
class DrawPolylineProfile(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.draw_polyline_profile"
|
||||
bl_label = "Draw Polyline Profile"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
@@ -1142,6 +1142,9 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
|
||||
DumbProfileJoiner().join_V(profile2["obj"], profile1["obj"])
|
||||
|
||||
def modal(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="MODAL")
|
||||
|
||||
def _modal(self, context, event):
|
||||
if not self.relating_type:
|
||||
self.report({"WARNING"}, "You need to select a profile type.")
|
||||
PolylineDecorator.uninstall()
|
||||
@@ -1192,6 +1195,9 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
super().invoke(context, event)
|
||||
ProductDecorator.install(context)
|
||||
self.tool_state.use_default_container = True
|
||||
|
||||
@@ -31,9 +31,8 @@ import bonsai.core.geometry
|
||||
import bonsai.core.root
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from math import cos, radians
|
||||
from math import cos
|
||||
from mathutils import Vector, Matrix
|
||||
from bonsai.bim.module.geometry.helper import Helper
|
||||
from bonsai.bim.module.model.decorator import ProfileDecorator, PolylineDecorator, ProductDecorator
|
||||
from bonsai.bim.module.model.polyline import PolylineOperator
|
||||
from bonsai.bim.module.model.wall import DumbWallRecalculator
|
||||
@@ -864,7 +863,7 @@ class AddSlabFromWall(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
||||
class DrawPolylineSlab(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.draw_polyline_slab"
|
||||
bl_label = "Draw Polyline Slab"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
@@ -905,6 +904,9 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
||||
DumbSlabPlaner().regenerate_from_occurence(element, material_set_usage)
|
||||
|
||||
def modal(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="MODAL")
|
||||
|
||||
def _modal(self, context, event):
|
||||
if not self.relating_type:
|
||||
self.report({"WARNING"}, "You need to select a slab type.")
|
||||
PolylineDecorator.uninstall()
|
||||
@@ -975,6 +977,9 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
super().invoke(context, event)
|
||||
ProductDecorator.install(context)
|
||||
self.tool_state.use_default_container = True
|
||||
|
||||
@@ -350,7 +350,7 @@ class AddWallsFromSlab(bpy.types.Operator, tool.Ifc.Operator):
|
||||
DumbWallJoiner().join_V(wall2["obj"], wall1["obj"])
|
||||
|
||||
|
||||
class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
||||
class DrawPolylineWall(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.draw_polyline_wall"
|
||||
bl_label = "Draw Polyline Wall"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
@@ -399,6 +399,9 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
||||
DumbWallJoiner().join_V(wall2["obj"], wall1["obj"])
|
||||
|
||||
def modal(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="MODAL")
|
||||
|
||||
def _modal(self, context, event):
|
||||
if not self.relating_type:
|
||||
self.report({"WARNING"}, "You need to select a wall type.")
|
||||
PolylineDecorator.uninstall()
|
||||
@@ -471,6 +474,9 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
super().invoke(context, event)
|
||||
ProductDecorator.install(context)
|
||||
self.tool_state.use_default_container = True
|
||||
|
||||
@@ -355,7 +355,7 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator):
|
||||
ifc_class: bpy.props.StringProperty(options={"SKIP_SAVE"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||
return IfcStore.execute_ifc_operator(self, context, event, method="INVOKE")
|
||||
|
||||
def _invoke(self, context, event):
|
||||
props = context.scene.BIMRootProperties
|
||||
|
||||
@@ -44,7 +44,7 @@ def set_shape_aspect_constituents(
|
||||
|
||||
A material may be associated with a style (i.e. colour). For example, a
|
||||
grey style for the "Aluminium" material and a transparent blue style for
|
||||
the "Laminated Low-e Glass" material.
|
||||
the "Laminated Low-e Glass" material.
|
||||
|
||||
These three concepts of material constituents, shape aspects, and
|
||||
associated styles are correlated. For example, if the name (e.g. "Framing")
|
||||
@@ -75,7 +75,7 @@ def set_shape_aspect_constituents(
|
||||
# Create two materials
|
||||
aluminium = ifcopenshell.api.material.add_material(model, name="AL01", category="aluminium")
|
||||
glass = ifcopenshell.api.material.add_material(model, name="GLZ01", category="glass")
|
||||
|
||||
|
||||
# Auto assign material constituents and styles to items based on shape aspects
|
||||
ifcopenshell.api.material.set_shape_aspect_constituents(
|
||||
model, element=window, context=body, materials={
|
||||
@@ -102,9 +102,7 @@ def set_shape_aspect_constituents(
|
||||
if should_create_new_material_set:
|
||||
material_set = ifcopenshell.api.material.add_material_set(file, set_type="IfcMaterialConstituentSet")
|
||||
for name, material in materials.items():
|
||||
ifcopenshell.api.material.add_constituent(
|
||||
file, constituent_set=material_set, material=material, name=name
|
||||
)
|
||||
ifcopenshell.api.material.add_constituent(file, constituent_set=material_set, material=material, name=name)
|
||||
ifcopenshell.api.material.assign_material(file, products=[element], material=material_set)
|
||||
|
||||
styles = {n: ifcopenshell.util.representation.get_material_style(m, context) for n, m in materials.items()}
|
||||
|
||||
Reference in New Issue
Block a user