Skip to content
This repository was archived by the owner on Nov 24, 2024. It is now read-only.

Commit 8b35a3a

Browse files
committed
Assign control to cost items and UX Workschedules and Costchedules cleanup
1 parent 78314b1 commit 8b35a3a

12 files changed

Lines changed: 502 additions & 272 deletions

File tree

src/blenderbim/blenderbim/bim/module/cost/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
operator.RemoveCostSchedule,
77
operator.EditCostSchedule,
88
operator.EnableEditingCostSchedule,
9+
operator.EnableEditingCostItems,
10+
operator.EnableEditingCostItem,
911
operator.DisableEditingCostSchedule,
1012
operator.AddCostItem,
1113
operator.AddSummaryCostItem,
1214
operator.ExpandCostItem,
1315
operator.ContractCostItem,
1416
operator.RemoveCostItem,
17+
operator.AssignControl,
18+
operator.UnassignControl,
1519
prop.CostItem,
1620
prop.BIMCostProperties,
1721
ui.BIM_PT_cost_schedules,

src/blenderbim/blenderbim/bim/module/cost/operator.py

Lines changed: 168 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@ def execute(self, context):
1515
return {"FINISHED"}
1616

1717

18+
class EditCostSchedule(bpy.types.Operator):
19+
bl_idname = "bim.edit_cost_schedule"
20+
bl_label = "Edit Cost Schedule"
21+
22+
def execute(self, context):
23+
props = context.scene.BIMCostProperties
24+
attributes = {}
25+
for attribute in props.cost_schedule_attributes:
26+
if attribute.is_null:
27+
attributes[attribute.name] = None
28+
else:
29+
if attribute.data_type == "string":
30+
attributes[attribute.name] = attribute.string_value
31+
elif attribute.data_type == "enum":
32+
attributes[attribute.name] = attribute.enum_value
33+
self.file = IfcStore.get_file()
34+
ifcopenshell.api.run(
35+
"cost.edit_cost_schedule",
36+
self.file,
37+
**{"cost_schedule": self.file.by_id(props.active_cost_schedule_id), "attributes": attributes},
38+
)
39+
Data.load(IfcStore.get_file())
40+
bpy.ops.bim.disable_editing_cost_schedule()
41+
return {"FINISHED"}
42+
43+
1844
class RemoveCostSchedule(bpy.types.Operator):
1945
bl_idname = "bim.remove_cost_schedule"
2046
bl_label = "Remove Cost Schedule"
@@ -38,10 +64,13 @@ class EnableEditingCostSchedule(bpy.types.Operator):
3864
def execute(self, context):
3965
self.props = context.scene.BIMCostProperties
4066
self.props.active_cost_schedule_id = self.cost_schedule
41-
4267
while len(self.props.cost_schedule_attributes) > 0:
4368
self.props.cost_schedule_attributes.remove(0)
69+
self.enable_editing_cost_schedule()
70+
self.props.is_editing = "COST_SCHEDULE"
71+
return {"FINISHED"}
4472

73+
def enable_editing_cost_schedule(self):
4574
data = Data.cost_schedules[self.cost_schedule]
4675

4776
for attribute in IfcStore.get_schema().declaration_by_name("IfcCostSchedule").all_attributes():
@@ -62,12 +91,22 @@ def execute(self, context):
6291
if data[attribute.name()]:
6392
new.enum_value = data[attribute.name()]
6493

94+
95+
class EnableEditingCostItems(bpy.types.Operator):
96+
bl_idname = "bim.enable_editing_cost_items"
97+
bl_label = "Enable Editing Cost Items"
98+
cost_schedule: bpy.props.IntProperty()
99+
100+
def execute(self, context):
101+
self.props = context.scene.BIMCostProperties
102+
self.props.active_cost_schedule_id = self.cost_schedule
65103
while len(self.props.cost_items) > 0:
66104
self.props.cost_items.remove(0)
67105

68106
self.contracted_cost_items = json.loads(self.props.contracted_cost_items)
69107
for related_object_id in Data.cost_schedules[self.cost_schedule]["RelatedObjects"]:
70108
self.create_new_cost_item_li(related_object_id, 0)
109+
self.props.is_editing = "COST_ITEMS"
71110
return {"FINISHED"}
72111

73112
def create_new_cost_item_li(self, related_object_id, level_index):
@@ -83,40 +122,15 @@ def create_new_cost_item_li(self, related_object_id, level_index):
83122
for related_object_id in cost_item["RelatedObjects"]:
84123
self.create_new_cost_item_li(related_object_id, level_index + 1)
85124

125+
return {"FINISHED"}
126+
86127

87128
class DisableEditingCostSchedule(bpy.types.Operator):
88129
bl_idname = "bim.disable_editing_cost_schedule"
89130
bl_label = "Disable Editing Cost Schedule"
90131

91132
def execute(self, context):
92-
props = context.scene.BIMCostProperties
93-
props.active_cost_schedule_id = 0
94-
return {"FINISHED"}
95-
96-
97-
class EditCostSchedule(bpy.types.Operator):
98-
bl_idname = "bim.edit_cost_schedule"
99-
bl_label = "Edit Cost Schedule"
100-
101-
def execute(self, context):
102-
props = context.scene.BIMCostProperties
103-
attributes = {}
104-
for attribute in props.cost_schedule_attributes:
105-
if attribute.is_null:
106-
attributes[attribute.name] = None
107-
else:
108-
if attribute.data_type == "string":
109-
attributes[attribute.name] = attribute.string_value
110-
elif attribute.data_type == "enum":
111-
attributes[attribute.name] = attribute.enum_value
112-
self.file = IfcStore.get_file()
113-
ifcopenshell.api.run(
114-
"cost.edit_cost_schedule",
115-
self.file,
116-
**{"cost_schedule": self.file.by_id(props.active_cost_schedule_id), "attributes": attributes}
117-
)
118-
Data.load(IfcStore.get_file())
119-
bpy.ops.bim.disable_editing_cost_schedule()
133+
context.scene.BIMCostProperties.active_cost_schedule_id = 0
120134
return {"FINISHED"}
121135

122136

@@ -130,7 +144,7 @@ def execute(self, context):
130144
self.file = IfcStore.get_file()
131145
ifcopenshell.api.run("cost.add_cost_item", self.file, **{"cost_schedule": self.file.by_id(self.cost_schedule)})
132146
Data.load(self.file)
133-
bpy.ops.bim.enable_editing_cost_schedule(cost_schedule=self.cost_schedule)
147+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=self.cost_schedule)
134148
return {"FINISHED"}
135149

136150

@@ -142,10 +156,9 @@ class AddCostItem(bpy.types.Operator):
142156
def execute(self, context):
143157
props = context.scene.BIMCostProperties
144158
self.file = IfcStore.get_file()
145-
data = {"cost_item": self.file.by_id(self.cost_item)}
146-
ifcopenshell.api.run("cost.add_cost_item", self.file, **data)
159+
ifcopenshell.api.run("cost.add_cost_item", self.file, **{"cost_item": self.file.by_id(self.cost_item)})
147160
Data.load(self.file)
148-
bpy.ops.bim.enable_editing_cost_schedule(cost_schedule=props.active_cost_schedule_id)
161+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
149162
return {"FINISHED"}
150163

151164

@@ -160,7 +173,7 @@ def execute(self, context):
160173
contracted_cost_items = json.loads(props.contracted_cost_items)
161174
contracted_cost_items.remove(self.cost_item)
162175
props.contracted_cost_items = json.dumps(contracted_cost_items)
163-
bpy.ops.bim.enable_editing_cost_schedule(cost_schedule=props.active_cost_schedule_id)
176+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
164177
return {"FINISHED"}
165178

166179

@@ -175,7 +188,7 @@ def execute(self, context):
175188
contracted_cost_items = json.loads(props.contracted_cost_items)
176189
contracted_cost_items.append(self.cost_item)
177190
props.contracted_cost_items = json.dumps(contracted_cost_items)
178-
bpy.ops.bim.enable_editing_cost_schedule(cost_schedule=props.active_cost_schedule_id)
191+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
179192
return {"FINISHED"}
180193

181194

@@ -197,5 +210,124 @@ def execute(self, context):
197210
contracted_cost_items.remove(props.active_cost_item_index)
198211
props.contracted_cost_items = json.dumps(contracted_cost_items)
199212
Data.load(self.file)
200-
bpy.ops.bim.enable_editing_cost_schedule(cost_schedule=props.active_cost_schedule_id)
213+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
214+
return {"FINISHED"}
215+
216+
217+
class EnableEditingCostItem(bpy.types.Operator):
218+
bl_idname = "bim.enable_editing_cost_item"
219+
bl_label = "Enable Editing Cost Item"
220+
cost_item: bpy.props.IntProperty()
221+
222+
def execute(self, context):
223+
props = context.scene.BIMCostProperties
224+
while len(props.cost_item_attributes) > 0:
225+
props.cost_item_attributes.remove(0)
226+
227+
data = Data.cost_items[self.cost_item]
228+
229+
for attribute in IfcStore.get_schema().declaration_by_name("IfcCostItem").all_attributes():
230+
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
231+
if data_type == "entity":
232+
continue
233+
new = props.cost_item_attributes.add()
234+
new.name = attribute.name()
235+
new.is_null = data[attribute.name()] is None
236+
new.is_optional = attribute.optional()
237+
new.data_type = data_type
238+
if data_type == "string":
239+
new.string_value = "" if new.is_null else data[attribute.name()]
240+
elif data_type == "boolean":
241+
new.bool_value = False if new.is_null else data[attribute.name()]
242+
elif data_type == "integer":
243+
new.int_value = 0 if new.is_null else data[attribute.name()]
244+
elif data_type == "enum":
245+
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
246+
if data[attribute.name()]:
247+
new.enum_value = data[attribute.name()]
248+
props.active_cost_item_id = self.cost_item
249+
return {"FINISHED"}
250+
251+
252+
class DisableEditingCostItem(bpy.types.Operator):
253+
bl_idname = "bim.disable_editing_cost_item"
254+
bl_label = "Disable Editing Cost Item"
255+
256+
def execute(self, context):
257+
context.scene.BIMCostProperties.active_cost_item_id = 0
258+
return {"FINISHED"}
259+
260+
261+
class EditCostItem(bpy.types.Operator):
262+
bl_idname = "bim.edit_cost_item"
263+
bl_label = "Edit Cost Item"
264+
265+
def execute(self, context):
266+
props = context.scene.BIMCostProperties
267+
attributes = {}
268+
for attribute in props.cost_item_attributes:
269+
if attribute.is_null:
270+
attributes[attribute.name] = None
271+
else:
272+
if attribute.data_type == "string":
273+
attributes[attribute.name] = attribute.string_value
274+
elif attribute.data_type == "boolean":
275+
attributes[attribute.name] = attribute.bool_value
276+
elif attribute.data_type == "integer":
277+
attributes[attribute.name] = attribute.int_value
278+
elif attribute.data_type == "enum":
279+
attributes[attribute.name] = attribute.enum_value
280+
self.file = IfcStore.get_file()
281+
ifcopenshell.api.run(
282+
"cost.edit_cost_item",
283+
self.file,
284+
**{"cost_item": self.file.by_id(props.active_cost_item_id), "attributes": attributes},
285+
)
286+
Data.load(IfcStore.get_file())
287+
bpy.ops.bim.disable_editing_cost_item()
288+
bpy.ops.bim.enable_editing_cost_items(cost_schedule=props.active_cost_schedule_id)
289+
return {"FINISHED"}
290+
291+
292+
class AssignControl(bpy.types.Operator):
293+
bl_idname = "bim.assign_control"
294+
bl_label = "Assign Control"
295+
cost_item: bpy.props.IntProperty()
296+
related_object: bpy.props.StringProperty()
297+
298+
def execute(self, context):
299+
related_objects = (
300+
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects
301+
)
302+
for related_object in related_objects:
303+
self.file = IfcStore.get_file()
304+
ifcopenshell.api.run(
305+
"control.assign_control",
306+
self.file,
307+
related_object=self.file.by_id(related_object.BIMObjectProperties.ifc_definition_id),
308+
relating_control=self.file.by_id(self.cost_item),
309+
)
310+
Data.load(self.file)
311+
return {"FINISHED"}
312+
313+
314+
class UnassignControl(bpy.types.Operator):
315+
bl_idname = "bim.unassign_control"
316+
bl_label = "Unassign Control"
317+
cost_item: bpy.props.IntProperty()
318+
related_object: bpy.props.StringProperty()
319+
320+
def execute(self, context):
321+
related_objects = (
322+
[bpy.data.objects.get(self.related_object)] if self.related_object else bpy.context.selected_objects
323+
)
324+
for related_object in related_objects:
325+
self.file = IfcStore.get_file()
326+
ifcopenshell.api.run(
327+
"control.unassign_control",
328+
self.file,
329+
related_object=self.file.by_id(related_object.BIMObjectProperties.ifc_definition_id),
330+
relating_control=self.file.by_id(self.cost_item),
331+
)
332+
Data.load(self.file)
201333
return {"FINISHED"}

src/blenderbim/blenderbim/bim/module/cost/prop.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import bpy
2+
import ifcopenshell.api
3+
from blenderbim.bim.ifc import IfcStore
4+
from ifcopenshell.api.cost.data import Data
25
from blenderbim.bim.prop import StrProperty, Attribute
36
from bpy.types import PropertyGroup
47
from bpy.props import (
@@ -13,8 +16,24 @@
1316
)
1417

1518

19+
def updateCostItemName(self, context):
20+
if self.name == "Unnamed":
21+
return
22+
self.file = IfcStore.get_file()
23+
props = context.scene.BIMCostProperties
24+
ifcopenshell.api.run(
25+
"cost.edit_cost_item",
26+
self.file,
27+
**{"cost_item": self.file.by_id(self.ifc_definition_id), "attributes": {"Name": self.name}},
28+
)
29+
Data.load(IfcStore.get_file())
30+
if props.active_cost_item_id == self.ifc_definition_id:
31+
attribute = props.cost_item_attributes.get("Name")
32+
attribute.string_value = self.name
33+
34+
1635
class CostItem(PropertyGroup):
17-
name: StringProperty(name="Name")
36+
name: StringProperty(name="Name", update=updateCostItemName)
1837
ifc_definition_id: IntProperty(name="IFC Definition ID")
1938
has_children: BoolProperty(name="Has Children")
2039
is_expanded: BoolProperty(name="Is Expanded")
@@ -23,7 +42,10 @@ class CostItem(PropertyGroup):
2342

2443
class BIMCostProperties(PropertyGroup):
2544
cost_schedule_attributes: CollectionProperty(name="Cost Schedule Attributes", type=Attribute)
45+
is_editing: StringProperty(name="Is Editing")
2646
active_cost_schedule_id: IntProperty(name="Active Cost Schedule Id")
2747
cost_items: CollectionProperty(name="Work Calendar", type=CostItem)
48+
active_cost_item_id: IntProperty(name="Active Cost Id")
2849
active_cost_item_index: IntProperty(name="Active Cost Item Index")
50+
cost_item_attributes: CollectionProperty(name="Task Attributes", type=Attribute)
2951
contracted_cost_items: StringProperty(name="Contracted Cost Items", default="[]")

0 commit comments

Comments
 (0)