mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 11:18:18 +00:00
Fix #1557. Surface style attributes can now be explicitly edited.
This commit is contained in:
@@ -83,7 +83,7 @@ class BIM_PT_object_attributes(Panel):
|
|||||||
|
|
||||||
|
|
||||||
class BIM_PT_material_attributes(Panel):
|
class BIM_PT_material_attributes(Panel):
|
||||||
bl_label = "IFC Attributes"
|
bl_label = "IFC Material Attributes"
|
||||||
bl_idname = "BIM_PT_material_attributes"
|
bl_idname = "BIM_PT_material_attributes"
|
||||||
bl_space_type = "PROPERTIES"
|
bl_space_type = "PROPERTIES"
|
||||||
bl_region_type = "WINDOW"
|
bl_region_type = "WINDOW"
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from . import ui, operator
|
from . import ui, prop, operator
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.AddStyle,
|
operator.AddStyle,
|
||||||
|
operator.EnableEditingStyle,
|
||||||
|
operator.DisableEditingStyle,
|
||||||
operator.EditStyle,
|
operator.EditStyle,
|
||||||
operator.RemoveStyle,
|
operator.RemoveStyle,
|
||||||
|
operator.UpdateStyleColours,
|
||||||
operator.UnlinkStyle,
|
operator.UnlinkStyle,
|
||||||
|
prop.BIMStyleProperties,
|
||||||
ui.BIM_PT_style,
|
ui.BIM_PT_style,
|
||||||
|
ui.BIM_PT_style_attributes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
pass
|
bpy.types.Material.BIMStyleProperties = bpy.props.PointerProperty(type=prop.BIMStyleProperties)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
pass
|
del bpy.types.Material.BIMStyleProperties
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
import blenderbim.bim.helper
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
from ifcopenshell.api.style.data import Data
|
||||||
|
|
||||||
|
|
||||||
def get_colour_settings(material):
|
def get_colour_settings(material):
|
||||||
@@ -18,9 +20,9 @@ def get_colour_settings(material):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class EditStyle(bpy.types.Operator):
|
class UpdateStyleColours(bpy.types.Operator):
|
||||||
bl_idname = "bim.edit_style"
|
bl_idname = "bim.update_style_colours"
|
||||||
bl_label = "Edit Style"
|
bl_label = "Update Style Colours"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
material: bpy.props.StringProperty()
|
material: bpy.props.StringProperty()
|
||||||
|
|
||||||
@@ -32,7 +34,7 @@ class EditStyle(bpy.types.Operator):
|
|||||||
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material
|
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material
|
||||||
settings = get_colour_settings(material)
|
settings = get_colour_settings(material)
|
||||||
settings["style"] = self.file.by_id(material.BIMMaterialProperties.ifc_style_id)
|
settings["style"] = self.file.by_id(material.BIMMaterialProperties.ifc_style_id)
|
||||||
ifcopenshell.api.run("style.edit_style", self.file, **settings)
|
ifcopenshell.api.run("style.edit_style_colours", self.file, **settings)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -88,3 +90,54 @@ class UnlinkStyle(bpy.types.Operator):
|
|||||||
if "Ifc" in material.name and "/" in material.name:
|
if "Ifc" in material.name and "/" in material.name:
|
||||||
material.name = "/".join(material.name.split("/")[1:])
|
material.name = "/".join(material.name.split("/")[1:])
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class EnableEditingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.enable_editing_style"
|
||||||
|
bl_label = "Enable Editing Style"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
material: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material
|
||||||
|
props = material.BIMStyleProperties
|
||||||
|
while len(props.attributes) > 0:
|
||||||
|
props.attributes.remove(0)
|
||||||
|
|
||||||
|
data = Data.styles[material.BIMMaterialProperties.ifc_style_id]
|
||||||
|
blenderbim.bim.helper.import_attributes("IfcSurfaceStyle", props.attributes, data)
|
||||||
|
props.is_editing_attributes = True
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class DisableEditingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.disable_editing_style"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_label = "Disable Editing Style"
|
||||||
|
material: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
material = bpy.data.materials.get(self.material) if self.material else bpy.context.active_object.active_material
|
||||||
|
props = material.BIMStyleProperties
|
||||||
|
props.is_editing_attributes = False
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class EditStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.edit_style"
|
||||||
|
bl_label = "Edit Style"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
return IfcStore.execute_ifc_operator(self, context)
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
material = bpy.context.active_object.active_material
|
||||||
|
props = material.BIMStyleProperties
|
||||||
|
attributes = blenderbim.bim.helper.export_attributes(props.attributes)
|
||||||
|
self.file = IfcStore.get_file()
|
||||||
|
style = self.file.by_id(material.BIMMaterialProperties.ifc_style_id)
|
||||||
|
ifcopenshell.api.run("style.edit_style", self.file, **{"style": style, "attributes": attributes})
|
||||||
|
Data.load(IfcStore.get_file(), material.BIMMaterialProperties.ifc_style_id)
|
||||||
|
bpy.ops.bim.disable_editing_style()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import bpy
|
||||||
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
|
from bpy.types import PropertyGroup
|
||||||
|
from bpy.props import (
|
||||||
|
PointerProperty,
|
||||||
|
StringProperty,
|
||||||
|
EnumProperty,
|
||||||
|
BoolProperty,
|
||||||
|
IntProperty,
|
||||||
|
FloatProperty,
|
||||||
|
FloatVectorProperty,
|
||||||
|
CollectionProperty,
|
||||||
|
)
|
||||||
|
|
||||||
|
class BIMStyleProperties(PropertyGroup):
|
||||||
|
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||||
|
is_editing_attributes: BoolProperty(name="Is Editing Attributes")
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import blenderbim.bim.helper
|
||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
from ifcopenshell.api.style.data import Data
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_style(Panel):
|
class BIM_PT_style(Panel):
|
||||||
@@ -21,10 +23,51 @@ class BIM_PT_style(Panel):
|
|||||||
props = context.active_object.active_material.BIMMaterialProperties
|
props = context.active_object.active_material.BIMMaterialProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
if props.ifc_style_id:
|
if props.ifc_style_id:
|
||||||
row.operator("bim.edit_style", icon="GREASEPENCIL")
|
row.operator("bim.update_style_colours", icon="GREASEPENCIL")
|
||||||
op = row.operator("bim.unlink_style", icon="UNLINKED", text="")
|
op = row.operator("bim.unlink_style", icon="UNLINKED", text="")
|
||||||
op.material = context.active_object.active_material.name
|
op.material = context.active_object.active_material.name
|
||||||
op = row.operator("bim.remove_style", icon="X", text="")
|
op = row.operator("bim.remove_style", icon="X", text="")
|
||||||
op.material = context.active_object.active_material.name
|
op.material = context.active_object.active_material.name
|
||||||
else:
|
else:
|
||||||
row.operator("bim.add_style", icon="ADD")
|
row.operator("bim.add_style", icon="ADD")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_style_attributes(Panel):
|
||||||
|
bl_label = "IFC Style Attributes"
|
||||||
|
bl_idname = "BIM_PT_style_attributes"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "material"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
try:
|
||||||
|
return bool(context.active_object.active_material.BIMMaterialProperties.ifc_style_id)
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
obj = context.active_object.active_material
|
||||||
|
mprops = obj.BIMMaterialProperties
|
||||||
|
props = obj.BIMStyleProperties
|
||||||
|
if mprops.ifc_style_id not in Data.styles:
|
||||||
|
Data.load(IfcStore.get_file(), mprops.ifc_style_id)
|
||||||
|
if props.is_editing_attributes:
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.operator("bim.edit_style", icon="CHECKMARK")
|
||||||
|
row.operator("bim.disable_editing_style", icon="CANCEL", text="")
|
||||||
|
blenderbim.bim.helper.draw_attributes(props.attributes, self.layout)
|
||||||
|
else:
|
||||||
|
row = self.layout.row()
|
||||||
|
row.operator("bim.enable_editing_style", icon="GREASEPENCIL", text="Edit")
|
||||||
|
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text="STEP ID")
|
||||||
|
row.label(text=str(mprops.ifc_style_id))
|
||||||
|
|
||||||
|
for name, value in Data.styles[mprops.ifc_style_id].items():
|
||||||
|
if name in ["id", "type", "Styles"]:
|
||||||
|
continue
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text=name)
|
||||||
|
row.label(text=str(value))
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
class Data:
|
||||||
|
styles = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def purge(cls):
|
||||||
|
cls.styles = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, file, style_id):
|
||||||
|
if not file:
|
||||||
|
return
|
||||||
|
data = file.by_id(style_id).get_info()
|
||||||
|
data["Styles"] = [s.id() for s in data["Styles"]]
|
||||||
|
cls.styles[style_id] = data
|
||||||
@@ -1,67 +1,10 @@
|
|||||||
class Usecase:
|
class Usecase:
|
||||||
def __init__(self, file, **settings):
|
def __init__(self, file, **settings):
|
||||||
self.file = file
|
self.file = file
|
||||||
self.settings = {
|
self.settings = {"style": None, "attributes": {}}
|
||||||
"style": None,
|
|
||||||
"surface_colour": [], # RGB
|
|
||||||
"diffuse_colour": [], # RGB
|
|
||||||
"transparency": 0,
|
|
||||||
"external_definition": {
|
|
||||||
"location": None,
|
|
||||||
"identification": None,
|
|
||||||
"name": "Name"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for key, value in settings.items():
|
for key, value in settings.items():
|
||||||
self.settings[key] = value
|
self.settings[key] = value
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
#has_external_definition = None
|
for name, value in self.settings["attributes"].items():
|
||||||
for element in self.file.traverse(self.settings["style"]):
|
setattr(self.settings["style"], name, value)
|
||||||
if element.is_a("IfcSurfaceStyleShading"):
|
|
||||||
if element.SurfaceColour:
|
|
||||||
self.update_colour_rgb(element.SurfaceColour, self.settings["surface_colour"])
|
|
||||||
else:
|
|
||||||
element.SurfaceColour = self.create_colour_rgb(self.settings["surface_colour"])
|
|
||||||
element.Transparency = (self.settings["transparency"] - 1) * -1
|
|
||||||
if element.is_a("IfcSurfaceStyleRendering"):
|
|
||||||
if element.DiffuseColour:
|
|
||||||
self.update_colour_rgb(element.DiffuseColour, self.settings["diffuse_colour"])
|
|
||||||
else:
|
|
||||||
element.DiffuseColour = self.create_colour_rgb(self.settings["diffuse_colour"])
|
|
||||||
# TODO: Move to separate usecase
|
|
||||||
#if element.is_a("IfcExternallyDefinedSurfaceStyle"):
|
|
||||||
# element.Location = self.settings["location"]
|
|
||||||
# element.Identification = self.settings["identification"]
|
|
||||||
# element.Name = self.settings["name"]
|
|
||||||
# has_external_definition = True
|
|
||||||
#if not has_external_definition:
|
|
||||||
# styles = list(self.settings["style"].Styles)
|
|
||||||
# styles.append(self.create_externally_defined_surface_style())
|
|
||||||
# self.settings["style"].Styles = styles
|
|
||||||
return self.settings["style"]
|
|
||||||
|
|
||||||
def create_surface_style_rendering(self):
|
|
||||||
return self.file.create_entity("IfcSurfaceStyleRendering", **{
|
|
||||||
"SurfaceColour": self.create_colour_rgb(self.settings["surface_colour"]),
|
|
||||||
"Transparency": (self.settings["transparency"] - 1) * -1,
|
|
||||||
"ReflectanceMethod": "NOTDEFINED",
|
|
||||||
"DiffuseColour": self.create_colour_rgb(self.settings["diffuse_colour"])
|
|
||||||
})
|
|
||||||
|
|
||||||
def create_externally_defined_surface_style(self):
|
|
||||||
self.file.create_entity(
|
|
||||||
"IfcExternallyDefinedSurfaceStyle", **{
|
|
||||||
"Location": self.settings["location"],
|
|
||||||
"Identification": self.settings["identification"],
|
|
||||||
"Name": self.settings["name"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_colour_rgb(self, colour):
|
|
||||||
return self.file.createIfcColourRgb(None, colour[0], colour[1], colour[2])
|
|
||||||
|
|
||||||
def update_colour_rgb(self, element, colour):
|
|
||||||
element[1] = colour[0]
|
|
||||||
element[2] = colour[1]
|
|
||||||
element[3] = colour[2]
|
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
class Usecase:
|
||||||
|
def __init__(self, file, **settings):
|
||||||
|
self.file = file
|
||||||
|
self.settings = {
|
||||||
|
"style": None,
|
||||||
|
"surface_colour": [], # RGB
|
||||||
|
"diffuse_colour": [], # RGB
|
||||||
|
"transparency": 0,
|
||||||
|
"external_definition": {
|
||||||
|
"location": None,
|
||||||
|
"identification": None,
|
||||||
|
"name": "Name"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for key, value in settings.items():
|
||||||
|
self.settings[key] = value
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
#has_external_definition = None
|
||||||
|
for element in self.file.traverse(self.settings["style"]):
|
||||||
|
if element.is_a("IfcSurfaceStyleShading"):
|
||||||
|
if element.SurfaceColour:
|
||||||
|
self.update_colour_rgb(element.SurfaceColour, self.settings["surface_colour"])
|
||||||
|
else:
|
||||||
|
element.SurfaceColour = self.create_colour_rgb(self.settings["surface_colour"])
|
||||||
|
element.Transparency = (self.settings["transparency"] - 1) * -1
|
||||||
|
if element.is_a("IfcSurfaceStyleRendering"):
|
||||||
|
if element.DiffuseColour:
|
||||||
|
self.update_colour_rgb(element.DiffuseColour, self.settings["diffuse_colour"])
|
||||||
|
else:
|
||||||
|
element.DiffuseColour = self.create_colour_rgb(self.settings["diffuse_colour"])
|
||||||
|
# TODO: Move to separate usecase
|
||||||
|
#if element.is_a("IfcExternallyDefinedSurfaceStyle"):
|
||||||
|
# element.Location = self.settings["location"]
|
||||||
|
# element.Identification = self.settings["identification"]
|
||||||
|
# element.Name = self.settings["name"]
|
||||||
|
# has_external_definition = True
|
||||||
|
#if not has_external_definition:
|
||||||
|
# styles = list(self.settings["style"].Styles)
|
||||||
|
# styles.append(self.create_externally_defined_surface_style())
|
||||||
|
# self.settings["style"].Styles = styles
|
||||||
|
return self.settings["style"]
|
||||||
|
|
||||||
|
def create_surface_style_rendering(self):
|
||||||
|
return self.file.create_entity("IfcSurfaceStyleRendering", **{
|
||||||
|
"SurfaceColour": self.create_colour_rgb(self.settings["surface_colour"]),
|
||||||
|
"Transparency": (self.settings["transparency"] - 1) * -1,
|
||||||
|
"ReflectanceMethod": "NOTDEFINED",
|
||||||
|
"DiffuseColour": self.create_colour_rgb(self.settings["diffuse_colour"])
|
||||||
|
})
|
||||||
|
|
||||||
|
def create_externally_defined_surface_style(self):
|
||||||
|
self.file.create_entity(
|
||||||
|
"IfcExternallyDefinedSurfaceStyle", **{
|
||||||
|
"Location": self.settings["location"],
|
||||||
|
"Identification": self.settings["identification"],
|
||||||
|
"Name": self.settings["name"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_colour_rgb(self, colour):
|
||||||
|
return self.file.createIfcColourRgb(None, colour[0], colour[1], colour[2])
|
||||||
|
|
||||||
|
def update_colour_rgb(self, element, colour):
|
||||||
|
element[1] = colour[0]
|
||||||
|
element[2] = colour[1]
|
||||||
|
element[3] = colour[2]
|
||||||
Reference in New Issue
Block a user