See #1848. Refactor constraint data class.

This commit is contained in:
Dion Moult
2023-01-30 11:47:02 +11:00
parent 044cd6e97b
commit 7a185e7f7c
5 changed files with 78 additions and 37 deletions
@@ -16,10 +16,7 @@
# You should have received a copy of the GNU General Public License # 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/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import os
import bpy import bpy
import ifcopenshell
import ifcopenshell.util.schema
import blenderbim.tool as tool import blenderbim.tool as tool
@@ -0,0 +1,59 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2023 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
import blenderbim.tool as tool
def refresh():
ConstraintsData.is_loaded = False
ObjectConstraintsData.is_loaded = False
class ConstraintsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"total_objectives": cls.total_objectives()}
cls.is_loaded = True
@classmethod
def total_objectives(cls):
return len(tool.Ifc.get().by_type("IfcObjective"))
class ObjectConstraintsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"constraints": cls.constraints()}
cls.is_loaded = True
@classmethod
def constraints(cls):
results = []
element = tool.Ifc.get_entity(bpy.context.active_object)
for rel in element.HasAssociations or []:
if rel.is_a("IfcRelAssociatesConstraint"):
constraint = rel.RelatingConstraint
results.append({"id": constraint.id(), "type": constraint.is_a(), "name": constraint.Name or "Unnamed"})
return results
@@ -21,8 +21,8 @@ import json
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.attribute import ifcopenshell.util.attribute
import blenderbim.bim.helper import blenderbim.bim.helper
import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.constraint.data import Data
class LoadObjectives(bpy.types.Operator): class LoadObjectives(bpy.types.Operator):
@@ -33,10 +33,10 @@ class LoadObjectives(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMConstraintProperties props = context.scene.BIMConstraintProperties
props.constraints.clear() props.constraints.clear()
for constraint_id, constraint in Data.objectives.items(): for constraint in tool.Ifc.get().by_type("IfcObjective"):
new = props.constraints.add() new = props.constraints.add()
new.name = constraint["Name"] or "Unnamed" new.name = constraint.Name or "Unnamed"
new.ifc_definition_id = constraint_id new.ifc_definition_id = constraint.id()
props.is_editing = "IfcObjective" props.is_editing = "IfcObjective"
bpy.ops.bim.disable_editing_constraint() bpy.ops.bim.disable_editing_constraint()
return {"FINISHED"} return {"FINISHED"}
@@ -62,11 +62,7 @@ class EnableEditingConstraint(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMConstraintProperties props = context.scene.BIMConstraintProperties
props.constraint_attributes.clear() props.constraint_attributes.clear()
blenderbim.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.constraint), props.constraint_attributes)
if props.is_editing == "IfcObjective":
data = Data.objectives[self.constraint]
blenderbim.bim.helper.import_attributes(props.is_editing, props.constraint_attributes, data)
props.active_constraint_id = self.constraint props.active_constraint_id = self.constraint
return {"FINISHED"} return {"FINISHED"}
@@ -91,7 +87,6 @@ class AddObjective(bpy.types.Operator):
def _execute(self, context): def _execute(self, context):
result = ifcopenshell.api.run("constraint.add_objective", IfcStore.get_file()) result = ifcopenshell.api.run("constraint.add_objective", IfcStore.get_file())
Data.load(IfcStore.get_file())
bpy.ops.bim.load_objectives() bpy.ops.bim.load_objectives()
bpy.ops.bim.enable_editing_constraint(constraint=result.id()) bpy.ops.bim.enable_editing_constraint(constraint=result.id())
return {"FINISHED"} return {"FINISHED"}
@@ -121,7 +116,6 @@ class EditObjective(bpy.types.Operator):
self.file, self.file,
**{"objective": self.file.by_id(props.active_constraint_id), "attributes": attributes} **{"objective": self.file.by_id(props.active_constraint_id), "attributes": attributes}
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_objectives() bpy.ops.bim.load_objectives()
return {"FINISHED"} return {"FINISHED"}
@@ -141,7 +135,6 @@ class RemoveConstraint(bpy.types.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"constraint.remove_constraint", self.file, **{"constraint": self.file.by_id(self.constraint)} "constraint.remove_constraint", self.file, **{"constraint": self.file.by_id(self.constraint)}
) )
Data.load(IfcStore.get_file())
if props.is_editing == "IfcObjective": if props.is_editing == "IfcObjective":
bpy.ops.bim.load_objectives() bpy.ops.bim.load_objectives()
return {"FINISHED"} return {"FINISHED"}
@@ -200,7 +193,6 @@ class AssignConstraint(bpy.types.Operator):
"constraint": self.file.by_id(self.constraint), "constraint": self.file.by_id(self.constraint),
} }
) )
Data.load(self.file, obj_id)
return {"FINISHED"} return {"FINISHED"}
@@ -229,5 +221,4 @@ class UnassignConstraint(bpy.types.Operator):
"constraint": self.file.by_id(self.constraint), "constraint": self.file.by_id(self.constraint),
} }
) )
Data.load(self.file, obj_id)
return {"FINISHED"} return {"FINISHED"}
@@ -19,7 +19,7 @@
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.helper import draw_attributes from blenderbim.bim.helper import draw_attributes
from ifcopenshell.api.constraint.data import Data from blenderbim.bim.module.constraint.data import ConstraintsData, ObjectConstraintsData
class BIM_PT_constraints(Panel): class BIM_PT_constraints(Panel):
@@ -36,14 +36,14 @@ class BIM_PT_constraints(Panel):
return IfcStore.get_file() return IfcStore.get_file()
def draw(self, context): def draw(self, context):
if not Data.is_loaded: if not ConstraintsData.is_loaded:
Data.load(IfcStore.get_file()) ConstraintsData.load()
self.props = context.scene.BIMConstraintProperties self.props = context.scene.BIMConstraintProperties
if not self.props.is_editing or self.props.is_editing == "IfcObjective": if not self.props.is_editing or self.props.is_editing == "IfcObjective":
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="{} Objectives Found".format(len(Data.objectives)), icon="LIGHT") row.label(text=f"{ConstraintsData.data['total_objectives']} Objectives Found", icon="LIGHT")
if self.props.is_editing == "IfcObjective": if self.props.is_editing == "IfcObjective":
row.operator("bim.disable_constraint_editing_ui", text="", icon="CHECKMARK") row.operator("bim.disable_constraint_editing_ui", text="", icon="CHECKMARK")
row.operator("bim.add_objective", text="", icon="ADD") row.operator("bim.add_objective", text="", icon="ADD")
@@ -85,33 +85,29 @@ class BIM_PT_object_constraints(Panel):
return bool(context.active_object.BIMObjectProperties.ifc_definition_id) return bool(context.active_object.BIMObjectProperties.ifc_definition_id)
def draw(self, context): def draw(self, context):
if not ObjectConstraintsData.is_loaded:
ObjectConstraintsData.load()
obj = context.active_object obj = context.active_object
self.oprops = obj.BIMObjectProperties self.oprops = obj.BIMObjectProperties
self.sprops = context.scene.BIMConstraintProperties self.sprops = context.scene.BIMConstraintProperties
self.props = obj.BIMObjectConstraintProperties self.props = obj.BIMObjectConstraintProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
if not Data.is_loaded:
Data.load(IfcStore.get_file())
if self.oprops.ifc_definition_id not in Data.products:
Data.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
self.draw_add_ui() self.draw_add_ui()
constraint_ids = Data.products[self.oprops.ifc_definition_id] if not ObjectConstraintsData.data["constraints"]:
if not constraint_ids:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="No Constraints", icon="LIGHT") row.label(text="No Constraints", icon="LIGHT")
for constraint_id in constraint_ids: for constraint in ObjectConstraintsData.data["constraints"]:
try: if constraint["type"] == "IfcObjective":
constraint = Data.objectives[constraint_id]
icon = "LIGHT" icon = "LIGHT"
except: else:
pass # Metric not implemented continue # Metric not implemented
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=constraint.get("Name") or "Unnamed") row.label(text=constraint["name"])
row.operator("bim.unassign_constraint", text="", icon="X").constraint = constraint_id row.operator("bim.unassign_constraint", text="", icon="X").constraint = constraint["id"]
def draw_add_ui(self): def draw_add_ui(self):
if self.props.is_adding: if self.props.is_adding:
@@ -43,8 +43,6 @@ class Usecase:
""" """
self.file = file self.file = file
self.settings = {"pset_template": pset_template} self.settings = {"pset_template": pset_template}
for key, value in settings.items():
self.settings[key] = value
def execute(self): def execute(self):
ifcopenshell.util.element.remove_deep(self.file, self.settings["pset_template"]) ifcopenshell.util.element.remove_deep(self.file, self.settings["pset_template"])