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

Commit ae0789e

Browse files
committed
New assign / unassign declaration usecase, minor code & formatting cleanup
1 parent 13d4a99 commit ae0789e

25 files changed

Lines changed: 287 additions & 226 deletions

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

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ def execute(self, context):
1616
for ifc_definition_id, work_plan in Data.work_plans.items():
1717
new = props.work_plans.add()
1818
new.ifc_definition_id = ifc_definition_id
19-
new.name = work_plan["Name"] or "Unnamed"
19+
new.name = work_plan["Name"] or "Unnamed"
2020
props.is_editing = True
2121
bpy.ops.bim.disable_editing_work_plan()
2222
return {"FINISHED"}
2323

24+
2425
class DisableWorkPlanEditingUI(bpy.types.Operator):
2526
bl_idname = "bim.disable_work_plan_editing_ui"
2627
bl_label = "Disable WorkPlan Editing UI"
@@ -58,25 +59,28 @@ def execute(self, context):
5859
attributes[attribute.name] = attribute.enum_value
5960
self.file = IfcStore.get_file()
6061
ifcopenshell.api.run(
61-
"sequence.edit_work_plan", self.file, **{"work_plan": self.file.by_id(props.active_work_plan_id), "attributes": attributes}
62+
"sequence.edit_work_plan",
63+
self.file,
64+
**{"work_plan": self.file.by_id(props.active_work_plan_id), "attributes": attributes}
6265
)
6366
Data.load(IfcStore.get_file())
6467
bpy.ops.bim.load_work_plans()
6568
return {"FINISHED"}
6669

70+
6771
class RemoveWorkPlan(bpy.types.Operator):
6872
bl_idname = "bim.remove_work_plan"
6973
bl_label = "Remove Work Plan"
7074
work_plan: bpy.props.IntProperty()
7175

7276
def execute(self, context):
73-
props = context.scene.BIMWorkPlanProperties
7477
self.file = IfcStore.get_file()
7578
ifcopenshell.api.run("sequence.remove_work_plan", self.file, **{"work_plan": self.file.by_id(self.work_plan)})
7679
Data.load(IfcStore.get_file())
7780
bpy.ops.bim.load_work_plans()
7881
return {"FINISHED"}
7982

83+
8084
class EnableEditingWorkPlan(bpy.types.Operator):
8185
bl_idname = "bim.enable_editing_work_plan"
8286
bl_label = "Enable Editing Work Plan"
@@ -98,7 +102,9 @@ def execute(self, context):
98102
new.is_null = data[attribute.name()] is None
99103
new.is_optional = attribute.optional()
100104
new.data_type = data_type
101-
if data_type == "string":
105+
if attribute.name() in ["CreationDate", "StartTime", "FinishTime"]:
106+
new.string_value = "" if new.is_null else data[attribute.name()].isoformat()
107+
elif data_type == "string":
102108
new.string_value = "" if new.is_null else data[attribute.name()]
103109
elif data_type == "enum":
104110
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
@@ -107,6 +113,7 @@ def execute(self, context):
107113
props.active_work_plan_id = self.work_plan
108114
return {"FINISHED"}
109115

116+
110117
class DisableEditingWorkPlan(bpy.types.Operator):
111118
bl_idname = "bim.disable_editing_work_plan"
112119
bl_label = "Disable Editing Work Plan"
@@ -115,6 +122,7 @@ def execute(self, context):
115122
context.scene.BIMWorkPlanProperties.active_work_plan_id = 0
116123
return {"FINISHED"}
117124

125+
118126
class LoadWorkSchedules(bpy.types.Operator):
119127
bl_idname = "bim.load_work_schedules"
120128
bl_label = "Load Work Schedules"
@@ -125,12 +133,13 @@ def execute(self, context):
125133
props.work_schedules.remove(0)
126134
for ifc_definition_id, work_schedule in Data.work_schedules.items():
127135
new = props.work_schedules.add()
128-
new.ifc_definition_id = ifc_definition_id or "Unnamed"
129-
new.name = work_schedule["Name"]
136+
new.ifc_definition_id = ifc_definition_id
137+
new.name = work_schedule["Name"] or "Unnamed"
130138
props.is_editing = True
131139
bpy.ops.bim.disable_editing_work_schedule()
132140
return {"FINISHED"}
133141

142+
134143
class DisableWorkScheduleEditingUI(bpy.types.Operator):
135144
bl_idname = "bim.disable_work_schedule_editing_ui"
136145
bl_label = "Disable WorkSchedule Editing UI"
@@ -145,7 +154,7 @@ class AddWorkSchedule(bpy.types.Operator):
145154
bl_label = "Add Work Schedule"
146155

147156
def execute(self, context):
148-
result = ifcopenshell.api.run("sequence.add_work_schedule", IfcStore.get_file())
157+
ifcopenshell.api.run("sequence.add_work_schedule", IfcStore.get_file())
149158
Data.load(IfcStore.get_file())
150159
bpy.ops.bim.load_work_schedules()
151160
return {"FINISHED"}
@@ -167,27 +176,31 @@ def execute(self, context):
167176
elif attribute.data_type == "enum":
168177
attributes[attribute.name] = attribute.enum_value
169178
self.file = IfcStore.get_file()
170-
ifcopenshell.api.run("sequence.edit_work_schedule", self.file, **{
171-
"work_schedule": self.file.by_id(props.active_work_schedule_id),
172-
"attributes": attributes
173-
})
179+
ifcopenshell.api.run(
180+
"sequence.edit_work_schedule",
181+
self.file,
182+
**{"work_schedule": self.file.by_id(props.active_work_schedule_id), "attributes": attributes}
183+
)
174184
Data.load(IfcStore.get_file())
175185
bpy.ops.bim.load_work_schedules()
176186
return {"FINISHED"}
177187

188+
178189
class RemoveWorkSchedule(bpy.types.Operator):
179190
bl_idname = "bim.remove_work_schedule"
180191
bl_label = "Remove Work Schedule"
181192
work_schedule: bpy.props.IntProperty()
182193

183194
def execute(self, context):
184-
props = context.scene.BIMWorkScheduleProperties
185195
self.file = IfcStore.get_file()
186-
ifcopenshell.api.run("sequence.remove_work_schedule", self.file, **{"work_schedule": self.file.by_id(self.work_schedule)})
187-
Data.load(IfcStore.get_file())
196+
ifcopenshell.api.run(
197+
"sequence.remove_work_schedule", self.file, **{"work_schedule": self.file.by_id(self.work_schedule)}
198+
)
199+
Data.load(self.file)
188200
bpy.ops.bim.load_work_schedules()
189201
return {"FINISHED"}
190202

203+
191204
class EnableEditingWorkSchedule(bpy.types.Operator):
192205
bl_idname = "bim.enable_editing_work_schedule"
193206
bl_label = "Enable Editing Work Schedule"
@@ -209,7 +222,9 @@ def execute(self, context):
209222
new.is_null = data[attribute.name()] is None
210223
new.is_optional = attribute.optional()
211224
new.data_type = data_type
212-
if data_type == "string":
225+
if attribute.name() in ["CreationDate", "StartTime", "FinishTime"]:
226+
new.string_value = "" if new.is_null else data[attribute.name()].isoformat()
227+
elif data_type == "string":
213228
new.string_value = "" if new.is_null else data[attribute.name()]
214229
elif data_type == "enum":
215230
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
@@ -238,12 +253,13 @@ def execute(self, context):
238253
props.work_calendars.remove(0)
239254
for ifc_definition_id, work_calendar in Data.work_calendars.items():
240255
new = props.work_calendars.add()
241-
new.ifc_definition_id = ifc_definition_id or "Unnamed"
242-
new.name = work_calendar["Name"]
256+
new.ifc_definition_id = ifc_definition_id
257+
new.name = work_calendar["Name"] or "Unnamed"
243258
props.is_editing = True
244259
bpy.ops.bim.disable_editing_work_calendar()
245260
return {"FINISHED"}
246261

262+
247263
class DisableWorkCalendarEditingUI(bpy.types.Operator):
248264
bl_idname = "bim.disable_work_calendar_editing_ui"
249265
bl_label = "Disable WorkCalendar Editing UI"
@@ -258,7 +274,7 @@ class AddWorkCalendar(bpy.types.Operator):
258274
bl_label = "Add Work Calendar"
259275

260276
def execute(self, context):
261-
result = ifcopenshell.api.run("sequence.add_work_calendar", IfcStore.get_file())
277+
ifcopenshell.api.run("sequence.add_work_calendar", IfcStore.get_file())
262278
Data.load(IfcStore.get_file())
263279
bpy.ops.bim.load_work_calendars()
264280
return {"FINISHED"}
@@ -280,27 +296,31 @@ def execute(self, context):
280296
elif attribute.data_type == "enum":
281297
attributes[attribute.name] = attribute.enum_value
282298
self.file = IfcStore.get_file()
283-
ifcopenshell.api.run("sequence.edit_work_calendar", self.file, **{
284-
"work_calendar": self.file.by_id(props.active_work_calendar_id),
285-
"attributes": attributes
286-
})
299+
ifcopenshell.api.run(
300+
"sequence.edit_work_calendar",
301+
self.file,
302+
**{"work_calendar": self.file.by_id(props.active_work_calendar_id), "attributes": attributes}
303+
)
287304
Data.load(IfcStore.get_file())
288305
bpy.ops.bim.load_work_calendars()
289306
return {"FINISHED"}
290307

308+
291309
class RemoveWorkCalendar(bpy.types.Operator):
292310
bl_idname = "bim.remove_work_calendar"
293311
bl_label = "Remove Work Plan"
294312
work_calendar: bpy.props.IntProperty()
295313

296314
def execute(self, context):
297-
props = context.scene.BIMWorkCalendarProperties
298315
self.file = IfcStore.get_file()
299-
ifcopenshell.api.run("sequence.remove_work_calendar", self.file, **{"work_calendar": self.file.by_id(self.work_calendar)})
300-
Data.load(IfcStore.get_file())
316+
ifcopenshell.api.run(
317+
"sequence.remove_work_calendar", self.file, **{"work_calendar": self.file.by_id(self.work_calendar)}
318+
)
319+
Data.load(self.file)
301320
bpy.ops.bim.load_work_calendars()
302321
return {"FINISHED"}
303322

323+
304324
class EnableEditingWorkCalendar(bpy.types.Operator):
305325
bl_idname = "bim.enable_editing_work_calendar"
306326
bl_label = "Enable Editing Work Plan"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@ class BIMWorkCalendarProperties(PropertyGroup):
6161
is_editing: BoolProperty(name="Is Editing", default=False)
6262
work_calendars: CollectionProperty(name="Work Calendar", type=WorkCalendar)
6363
active_work_calendar_index: IntProperty(name="Active Work Calendar Index")
64-
active_work_calendar_id: IntProperty(name="Active Work Calendar Id")
64+
active_work_calendar_id: IntProperty(name="Active Work Calendar Id")

src/blenderbim/blenderbim/bim/module/sequence/ui.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ def draw(self, context):
4343
def draw_editable_ui(self, context):
4444
for attribute in self.props.work_plan_attributes:
4545
row = self.layout.row(align=True)
46-
row.prop(attribute, "string_value", text=attribute.name)
46+
if attribute.data_type == "string":
47+
row.prop(attribute, "string_value", text=attribute.name)
48+
elif attribute.data_type == "enum":
49+
row.prop(attribute, "enum_value", text=attribute.name)
4750
if attribute.is_optional:
4851
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
4952

@@ -104,10 +107,14 @@ def draw(self, context):
104107
def draw_editable_ui(self, context):
105108
for attribute in self.props.work_schedule_attributes:
106109
row = self.layout.row(align=True)
107-
row.prop(attribute, "string_value", text=attribute.name)
110+
if attribute.data_type == "string":
111+
row.prop(attribute, "string_value", text=attribute.name)
112+
elif attribute.data_type == "enum":
113+
row.prop(attribute, "enum_value", text=attribute.name)
108114
if attribute.is_optional:
109115
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
110116

117+
111118
class BIM_UL_work_schedules(UIList):
112119
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
113120
if item:
@@ -123,6 +130,7 @@ def draw_item(self, context, layout, data, item, icon, active_data, active_propn
123130
op.work_schedule = item.ifc_definition_id
124131
row.operator("bim.remove_work_schedule", text="", icon="X").work_schedule = item.ifc_definition_id
125132

133+
126134
class BIM_PT_work_calendars(Panel):
127135
bl_label = "IFC Work Calendars"
128136
bl_idname = "BIM_PT_work_calendars"
@@ -163,10 +171,14 @@ def draw(self, context):
163171
def draw_editable_ui(self, context):
164172
for attribute in self.props.work_calendar_attributes:
165173
row = self.layout.row(align=True)
166-
row.prop(attribute, "string_value", text=attribute.name)
174+
if attribute.data_type == "string":
175+
row.prop(attribute, "string_value", text=attribute.name)
176+
elif attribute.data_type == "enum":
177+
row.prop(attribute, "enum_value", text=attribute.name)
167178
if attribute.is_optional:
168179
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
169180

181+
170182
class BIM_UL_work_calendars(UIList):
171183
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
172184
if item:
@@ -230,4 +242,4 @@ def draw_item(self, context, layout, data, item, icon, active_data, active_propn
230242
row = layout.row(align=True)
231243
if item.identification:
232244
layout.label(text=item.identification)
233-
layout.label(text=item.name)
245+
layout.label(text=item.name)

src/ifcopenshell-python/ifcopenshell/api/aggregate/assign_object.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ def execute(self):
3636
self.file.remove(decomposes)
3737

3838
if is_decomposed_by:
39-
related_objects = list(is_decomposed_by.RelatedObjects)
40-
related_objects.append(self.settings["product"])
41-
is_decomposed_by.RelatedObjects = related_objects
39+
related_objects = set(is_decomposed_by.RelatedObjects)
40+
related_objects.add(self.settings["product"])
41+
is_decomposed_by.RelatedObjects = list(related_objects)
4242
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": is_decomposed_by})
4343
else:
4444
is_decomposed_by = self.file.create_entity(

src/ifcopenshell-python/ifcopenshell/api/constraint/unassign_constraint.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import ifcopenshell
2-
3-
41
class Usecase:
52
def __init__(self, file, **settings):
63
self.file = file
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import ifcopenshell
2+
import ifcopenshell.api
3+
4+
5+
class Usecase:
6+
def __init__(self, file, **settings):
7+
self.file = file
8+
self.settings = {
9+
"definition": None,
10+
"relating_context": None,
11+
}
12+
for key, value in settings.items():
13+
self.settings[key] = value
14+
15+
def execute(self):
16+
declares = None
17+
if self.settings["relating_context"].Declares:
18+
declares = self.settings["relating_context"].Declares[0]
19+
20+
has_context = None
21+
if self.settings["definition"].HasContext:
22+
has_context = self.settings["definition"].HasContext[0]
23+
24+
if has_context and has_context == declares:
25+
return
26+
27+
if has_context:
28+
related_definitions = list(has_context.RelatedDefinitions)
29+
related_definitions.remove(self.settings["definition"])
30+
if related_definitions:
31+
has_context.RelatedDefinitions = related_definitions
32+
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": has_context})
33+
else:
34+
self.file.remove(has_context)
35+
36+
if declares:
37+
related_definitions = set(declares.RelatedDefinitions)
38+
related_definitions.add(self.settings["definition"])
39+
declares.RelatedDefinitions = list(related_definitions)
40+
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": declares})
41+
else:
42+
declares = self.file.create_entity(
43+
"IfcRelDeclares",
44+
**{
45+
"GlobalId": ifcopenshell.guid.new(),
46+
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
47+
"RelatedDefinitions": [self.settings["definition"]],
48+
"RelatingContext": self.settings["relating_context"],
49+
}
50+
)
51+
return declares
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import ifcopenshell
2+
import ifcopenshell.api
3+
4+
5+
class Usecase:
6+
def __init__(self, file, **settings):
7+
self.file = file
8+
self.settings = {
9+
"definition": None,
10+
"relating_context": None,
11+
}
12+
for key, value in settings.items():
13+
self.settings[key] = value
14+
15+
def execute(self):
16+
if not self.settings["definition"].HasContext:
17+
return
18+
rel = self.settings["definition"].HasContext[0]
19+
related_definitions = set(rel.RelatedDefinitions) or set()
20+
related_definitions.remove(self.settings["definition"])
21+
if len(related_definitions):
22+
rel.RelatedDefinitions = list(related_definitions)
23+
ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": rel})
24+
else:
25+
self.file.remove(rel)

src/ifcopenshell-python/ifcopenshell/api/pset/add_pset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def execute(self):
2727
pset = self.file.create_entity(
2828
"IfcPropertySet", **{"GlobalId": ifcopenshell.guid.new(), "Name": self.settings["Name"]}
2929
)
30-
has_property_sets = list(self.settings["product"].HasPropertySets)
30+
has_property_sets = list(self.settings["product"].HasPropertySets or [])
3131
has_property_sets.append(pset)
3232
self.settings["product"].HasPropertySets = has_property_sets
3333
elif self.settings["product"].is_a("IfcMaterialDefinition"):

0 commit comments

Comments
 (0)