Skip to content

Commit 28cc168

Browse files
committed
split material assign/unassign operators into tool and core
1 parent 88f53f7 commit 28cc168

4 files changed

Lines changed: 109 additions & 81 deletions

File tree

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

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -174,67 +174,7 @@ class AssignMaterial(bpy.types.Operator, tool.Ifc.Operator):
174174

175175
def _execute(self, context):
176176
objects = [bpy.data.objects.get(self.obj)] if self.obj else tool.Blender.get_selected_objects()
177-
active_obj = context.active_object
178-
active_object_material_type = self.material_type or active_obj.BIMObjectMaterialProperties.material_type
179-
material = tool.Ifc.get().by_id(int(active_obj.BIMObjectMaterialProperties.material))
180-
for obj in objects:
181-
element = tool.Ifc.get_entity(obj)
182-
if not element:
183-
continue
184-
ifcopenshell.api.run(
185-
"material.assign_material",
186-
tool.Ifc.get(),
187-
product=element,
188-
type=active_object_material_type,
189-
material=material,
190-
)
191-
assigned_material = ifcopenshell.util.element.get_material(element)
192-
if assigned_material.is_a("IfcMaterialConstituentSet"):
193-
if not assigned_material.MaterialConstituents:
194-
ifcopenshell.api.run(
195-
"material.add_constituent",
196-
tool.Ifc.get(),
197-
constituent_set=assigned_material,
198-
material=material,
199-
)
200-
elif assigned_material.is_a() == "IfcMaterialLayerSet":
201-
if not assigned_material.MaterialLayers:
202-
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
203-
layer = ifcopenshell.api.run(
204-
"material.add_layer",
205-
tool.Ifc.get(),
206-
layer_set=assigned_material,
207-
material=material,
208-
)
209-
thickness = 0.1 # Arbitrary metric thickness for now
210-
layer.LayerThickness = thickness / unit_scale
211-
elif assigned_material.is_a("IfcMaterialProfileSet"):
212-
if not assigned_material.MaterialProfiles:
213-
named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName]
214-
if named_profiles:
215-
profile = named_profiles[0]
216-
else:
217-
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
218-
size = 0.5 / unit_scale
219-
profile = tool.Ifc.get().create_entity(
220-
"IfcRectangleProfileDef",
221-
ProfileName="New Profile",
222-
ProfileType="AREA",
223-
XDim=size,
224-
YDim=size,
225-
)
226-
material_profile = ifcopenshell.api.run(
227-
"material.add_profile",
228-
tool.Ifc.get(),
229-
profile_set=assigned_material,
230-
material=tool.Ifc.get().by_type("IfcMaterial")[0],
231-
)
232-
ifcopenshell.api.run(
233-
"material.assign_profile",
234-
tool.Ifc.get(),
235-
material_profile=material_profile,
236-
profile=profile,
237-
)
177+
core.assign_material(tool.Ifc, tool.Material, material_type= self.material_type , objects=objects )
238178

239179

240180
class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator):
@@ -245,20 +185,7 @@ class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator):
245185

246186
def _execute(self, context):
247187
objects = [bpy.data.objects.get(self.obj)] if self.obj else tool.Blender.get_selected_objects()
248-
for obj in objects:
249-
element = tool.Ifc.get_entity(obj)
250-
if element:
251-
material = ifcopenshell.util.element.get_material(element, should_inherit=False)
252-
inherited_material = ifcopenshell.util.element.get_material(element, should_inherit=True)
253-
print(material, inherited_material)
254-
if material and "Usage" in material.is_a():
255-
element_type = ifcopenshell.util.element.get_type(element)
256-
ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element_type)
257-
elif not material and inherited_material:
258-
element_type = ifcopenshell.util.element.get_type(element)
259-
ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element_type)
260-
elif material:
261-
ifcopenshell.api.run("material.unassign_material", tool.Ifc.get(), product=element)
188+
core.unassign_material(tool.Ifc, tool.Material, objects=objects )
262189

263190

264191
class AddConstituent(bpy.types.Operator, tool.Ifc.Operator):

src/blenderbim/blenderbim/core/material.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,32 @@ def edit_material(ifc, material_tool, material):
9090

9191
def disable_editing_material(material_tool):
9292
material_tool.disable_editing_material()
93+
94+
95+
def assign_material(ifc, material_tool, material_type, objects):
96+
material_type = material_type or material_tool.get_active_object_material()
97+
material = material_tool.get_active_material()
98+
for obj in objects:
99+
element = ifc.get_entity(obj)
100+
if not element:
101+
continue
102+
ifc.run("material.assign_material", product=element, type=material_type, material=material)
103+
assigned_material = material_tool.get_material(element)
104+
if material_tool.is_a_material_set(assigned_material):
105+
material_tool.add_material_to_set(material_set=assigned_material, material=material)
106+
107+
108+
def unassign_material(ifc, material_tool, objects):
109+
for obj in objects:
110+
element = ifc.get_entity(obj)
111+
if element:
112+
material = material_tool.get_material(element, should_inherit=False)
113+
inherited_material = material_tool.get_material(element, should_inherit=True)
114+
if material and "Usage" in material.is_a():
115+
element_type = material_tool.get_type(element)
116+
ifc.run("material.unassign_material", product=element_type)
117+
elif not material and inherited_material:
118+
element_type = material_tool.get_type(element)
119+
ifc.run("material.unassign_material", product=element_type)
120+
elif material:
121+
ifc.run("material.unassign_material", product=element)

src/blenderbim/blenderbim/core/tool.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,17 +433,22 @@ class Loader:
433433
@interface
434434
class Material:
435435
def add_default_material_object(cls): pass
436+
def add_material_to_set(cls, material_set, material): pass
436437
def delete_object(cls, obj): pass
437438
def disable_editing_material(cls): pass
438439
def disable_editing_materials(cls): pass
439440
def enable_editing_material(cls, material): pass
440441
def enable_editing_materials(cls): pass
441442
def get_active_material_type(cls): pass
442-
def get_active_material_type(cls): pass
443+
def get_active_material(cls): pass
444+
def get_active_object_material(cls, obj): pass
443445
def get_elements_by_material(cls, material): pass
444446
def get_material_attributes(cls): pass
447+
def get_material(cls, element, should_inherit): pass
445448
def get_name(cls, obj): pass
449+
def get_type(cls, element): pass
446450
def import_material_definitions(cls, material_type): pass
451+
def is_a_material_set(cls, material): pass
447452
def is_editing_materials(cls): pass
448453
def is_material_used_in_sets(cls, material): pass
449454
def load_material_attributes(cls, material): pass

src/blenderbim/blenderbim/tool/material.py

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import blenderbim.core.tool
2222
import blenderbim.tool as tool
2323
import blenderbim.bim.helper
24+
import ifcopenshell.util.unit
25+
import ifcopenshell.util.element
2426

2527

2628
class Material(blenderbim.core.tool.Material):
@@ -101,10 +103,6 @@ def is_material_used_in_sets(cls, material):
101103
return True
102104
return False
103105

104-
@classmethod
105-
def get_active_material_type(cls):
106-
return bpy.context.scene.BIMMaterialProperties.material_type
107-
108106
@classmethod
109107
def load_material_attributes(cls, material):
110108
props = bpy.context.scene.BIMMaterialProperties
@@ -115,7 +113,7 @@ def load_material_attributes(cls, material):
115113
def enable_editing_material(cls, material):
116114
props = bpy.context.scene.BIMMaterialProperties
117115
props.active_material_id = material.id()
118-
props.editing_material_type = "ATTRIBUTES"
116+
props.editing_material_type = "ATTRIBUTES"
119117

120118
@classmethod
121119
def get_material_attributes(cls):
@@ -126,3 +124,72 @@ def disable_editing_material(cls):
126124
props = bpy.context.scene.BIMMaterialProperties
127125
props.active_material_id = 0
128126
props.editing_material_type = ""
127+
128+
@classmethod
129+
def get_type(cls, element):
130+
return ifcopenshell.util.element.get_type(element)
131+
132+
@classmethod
133+
def get_active_object_material(cls):
134+
active_obj = bpy.context.active_object
135+
if not active_obj:
136+
return
137+
return active_obj.BIMObjectMaterialProperties.material_type
138+
139+
@classmethod
140+
def get_active_material(cls):
141+
return tool.Ifc.get().by_id(int(bpy.context.active_object.BIMObjectMaterialProperties.material))
142+
143+
@classmethod
144+
def get_material(cls, element, should_inherit=False):
145+
return ifcopenshell.util.element.get_material(element, should_inherit=should_inherit)
146+
147+
@classmethod
148+
def is_a_material_set(cls, material):
149+
return material.is_a() in [
150+
"IfcMaterialProfile",
151+
"IfcMaterialLayer",
152+
"IfcMaterialConstituent",
153+
"IfcMaterialList",
154+
]
155+
156+
@classmethod
157+
def add_material_to_set(cls, material_set, material):
158+
if material_set.is_a("IfcMaterialConstituentSet"):
159+
if not material_set.MaterialConstituents:
160+
tool.Ifc.run(
161+
"material.add_constituent",
162+
constituent_set=material_set,
163+
material=material,
164+
)
165+
elif material_set.is_a() == "IfcMaterialLayerSet":
166+
if not material_set.MaterialLayers:
167+
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
168+
layer = tool.Ifc.run(
169+
"material.add_layer",
170+
layer_set=material_set,
171+
material=material,
172+
)
173+
thickness = 0.1 # Arbitrary metric thickness for now
174+
layer.LayerThickness = thickness / unit_scale
175+
elif material_set.is_a("IfcMaterialProfileSet"):
176+
if not material_set.MaterialProfiles:
177+
named_profiles = [p for p in tool.Ifc.get().by_type("IfcProfileDef") if p.ProfileName]
178+
if named_profiles:
179+
profile = named_profiles[0]
180+
else:
181+
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
182+
size = 0.5 / unit_scale
183+
profile = tool.Ifc.get().create_entity(
184+
"IfcRectangleProfileDef",
185+
ProfileName="New Profile",
186+
ProfileType="AREA",
187+
XDim=size,
188+
YDim=size,
189+
)
190+
material_profile = ifcopenshell.api.run(
191+
"material.add_profile",
192+
profile_set=material_set,
193+
material=material,
194+
profile=profile,
195+
)

0 commit comments

Comments
 (0)