mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
You can now edit rendering styles in the style manager
This commit is contained in:
@@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from ifcopenshell.util.doc import get_entity_doc
|
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
from ifcopenshell.util.doc import get_entity_doc
|
||||||
|
|
||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
@@ -33,9 +33,18 @@ class StylesData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls):
|
def load(cls):
|
||||||
cls.data = {"style_types": cls.style_types(), "total_styles": cls.total_styles()}
|
cls.data = {
|
||||||
|
"style_types": cls.style_types(),
|
||||||
|
"total_styles": cls.total_styles(),
|
||||||
|
"reflectance_methods": cls.reflectance_methods(),
|
||||||
|
}
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def reflectance_methods(cls):
|
||||||
|
declaration = tool.Ifc.schema().declaration_by_name("IfcReflectanceMethodEnum")
|
||||||
|
return [(i, i, "") for i in declaration.enumeration_items()]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def style_types(cls):
|
def style_types(cls):
|
||||||
declaration = tool.Ifc.schema().declaration_by_name("IfcPresentationStyle")
|
declaration = tool.Ifc.schema().declaration_by_name("IfcPresentationStyle")
|
||||||
|
|||||||
@@ -492,20 +492,60 @@ class EnableEditingSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
props = bpy.context.scene.BIMStylesProperties
|
props = bpy.context.scene.BIMStylesProperties
|
||||||
style = tool.Ifc.get().by_id(self.style)
|
style = tool.Ifc.get().by_id(self.style)
|
||||||
|
|
||||||
|
shading = None
|
||||||
|
|
||||||
surface_style = None
|
surface_style = None
|
||||||
for style2 in style.Styles:
|
for style2 in style.Styles:
|
||||||
if style2.is_a() == self.ifc_class:
|
if style2.is_a() == self.ifc_class:
|
||||||
surface_style = style2
|
surface_style = style2
|
||||||
break
|
if style2.is_a() == "IfcSurfaceStyleShading":
|
||||||
|
shading = style2
|
||||||
|
|
||||||
|
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
|
||||||
|
|
||||||
if surface_style:
|
if surface_style:
|
||||||
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
|
|
||||||
if self.ifc_class == "IfcSurfaceStyleShading":
|
if self.ifc_class == "IfcSurfaceStyleShading":
|
||||||
props.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
props.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
||||||
props.transparency = surface_style.Transparency or 0.
|
props.transparency = surface_style.Transparency or 0.0
|
||||||
elif self.ifc_class == "IfcSurfaceStyleRendering":
|
elif self.ifc_class == "IfcSurfaceStyleRendering":
|
||||||
props.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
props.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
||||||
props.transparency = surface_style.Transparency or 0.
|
props.transparency = surface_style.Transparency or 0.0
|
||||||
|
|
||||||
|
if surface_style.DiffuseColour:
|
||||||
|
props.is_diffuse_colour_null = False
|
||||||
|
if surface_style.DiffuseColour.is_a("IfcColourRgb"):
|
||||||
|
props.diffuse_colour_class = "IfcColourRgb"
|
||||||
|
props.diffuse_colour = color_to_tuple(surface_style.DiffuseColour)
|
||||||
|
else:
|
||||||
|
props.diffuse_colour_class = "IfcNormalisedRatioMeasure"
|
||||||
|
props.diffuse_colour_ratio = surface_style.DiffuseColour.wrappedValue
|
||||||
|
else:
|
||||||
|
props.is_diffuse_colour_null = False
|
||||||
|
|
||||||
|
if surface_style.SpecularColour:
|
||||||
|
props.is_specular_colour_null = False
|
||||||
|
if surface_style.SpecularColour.is_a("IfcColourRgb"):
|
||||||
|
props.specular_colour_class = "IfcColourRgb"
|
||||||
|
props.specular_colour = color_to_tuple(surface_style.SpecularColour)
|
||||||
|
else:
|
||||||
|
props.specular_colour_class = "IfcNormalisedRatioMeasure"
|
||||||
|
props.specular_colour_ratio = surface_style.SpecularColour.wrappedValue
|
||||||
|
else:
|
||||||
|
props.is_specular_colour_null = False
|
||||||
|
|
||||||
|
if surface_style.SpecularHighlight:
|
||||||
|
props.is_specular_highlight_null = False
|
||||||
|
if surface_style.SpecularHighlight.is_a("IfcSpecularRoughness"):
|
||||||
|
props.specular_highlight = surface_style.SpecularHighlight.wrappedValue
|
||||||
|
else:
|
||||||
|
props.is_specular_highlight_null = False # Exponent is meaningless
|
||||||
|
else:
|
||||||
|
props.is_specular_highlight_null = True
|
||||||
|
|
||||||
|
props.reflectance_method = surface_style.ReflectanceMethod
|
||||||
|
elif shading:
|
||||||
|
props.surface_colour = color_to_tuple(shading.SurfaceColour)
|
||||||
|
props.transparency = shading.Transparency or 0.0
|
||||||
|
|
||||||
props.is_editing_style = self.style
|
props.is_editing_style = self.style
|
||||||
props.is_editing_class = self.ifc_class
|
props.is_editing_class = self.ifc_class
|
||||||
@@ -518,12 +558,12 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = bpy.context.scene.BIMStylesProperties
|
self.props = bpy.context.scene.BIMStylesProperties
|
||||||
style = tool.Ifc.get().by_id(self.props.is_editing_style)
|
self.style = tool.Ifc.get().by_id(self.props.is_editing_style)
|
||||||
|
|
||||||
self.surface_style = None
|
self.surface_style = None
|
||||||
self.shading_style = None
|
self.shading_style = None
|
||||||
self.rendering_style = None
|
self.rendering_style = None
|
||||||
for style2 in style.Styles:
|
for style2 in self.style.Styles:
|
||||||
if style2.is_a() == self.props.is_editing_class:
|
if style2.is_a() == self.props.is_editing_class:
|
||||||
self.surface_style = style2
|
self.surface_style = style2
|
||||||
if style2.is_a() == "IfcSurfaceStyleShading":
|
if style2.is_a() == "IfcSurfaceStyleShading":
|
||||||
@@ -541,10 +581,75 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def edit_existing_style(self):
|
def edit_existing_style(self):
|
||||||
if self.surface_style.is_a() == "IfcSurfaceStyleShading":
|
if self.surface_style.is_a() == "IfcSurfaceStyleShading":
|
||||||
self.surface_style.SurfaceColour.Red = self.props.surface_colour[0]
|
ifcopenshell.api.run(
|
||||||
self.surface_style.SurfaceColour.Green = self.props.surface_colour[1]
|
"style.edit_surface_style",
|
||||||
self.surface_style.SurfaceColour.Blue = self.props.surface_colour[2]
|
tool.Ifc.get(),
|
||||||
self.surface_style.Transparency = self.props.transparency or None
|
style=self.surface_style,
|
||||||
|
attributes={
|
||||||
|
"SurfaceColour": self.color_to_dict(self.props.surface_colour),
|
||||||
|
"Transparency": self.props.transparency or None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
elif self.surface_style.is_a() == "IfcSurfaceStyleRendering":
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"style.edit_surface_style",
|
||||||
|
tool.Ifc.get(),
|
||||||
|
style=self.surface_style,
|
||||||
|
attributes=self.get_rendering_attributes(),
|
||||||
|
)
|
||||||
|
|
||||||
def add_new_style(self):
|
def add_new_style(self):
|
||||||
pass
|
if self.props.is_editing_class == "IfcSurfaceStyleShading":
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"style.add_surface_style",
|
||||||
|
tool.Ifc.get(),
|
||||||
|
style=self.style,
|
||||||
|
ifc_class="IfcSurfaceStyleShading",
|
||||||
|
attributes=self.get_shading_attributes(),
|
||||||
|
)
|
||||||
|
elif self.props.is_editing_class == "IfcSurfaceStyleRendering":
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"style.add_surface_style",
|
||||||
|
tool.Ifc.get(),
|
||||||
|
style=self.style,
|
||||||
|
ifc_class="IfcSurfaceStyleRendering",
|
||||||
|
attributes=self.get_rendering_attributes(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_shading_attributes(self):
|
||||||
|
return {
|
||||||
|
"SurfaceColour": self.color_to_dict(self.props.surface_colour),
|
||||||
|
"Transparency": self.props.transparency or None,
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_rendering_attributes(self):
|
||||||
|
if self.props.is_diffuse_colour_null:
|
||||||
|
diffuse_colour = None
|
||||||
|
elif self.props.diffuse_colour_class == "IfcColourRgb":
|
||||||
|
diffuse_colour = self.color_to_dict(self.props.diffuse_colour)
|
||||||
|
elif self.props.diffuse_colour_class == "IfcNormalisedRatioMeasure":
|
||||||
|
diffuse_colour = self.props.diffuse_colour_ratio
|
||||||
|
|
||||||
|
if self.props.is_specular_colour_null:
|
||||||
|
specular_colour = None
|
||||||
|
elif self.props.specular_colour_class == "IfcColourRgb":
|
||||||
|
specular_colour = self.color_to_dict(self.props.specular_colour)
|
||||||
|
elif self.props.specular_colour_class == "IfcNormalisedRatioMeasure":
|
||||||
|
specular_colour = self.props.specular_colour_ratio
|
||||||
|
|
||||||
|
if self.props.is_specular_highlight_null:
|
||||||
|
specular_highlight = None
|
||||||
|
else:
|
||||||
|
specular_highlight = {"SpecularRoughness": self.props.specular_highlight}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"SurfaceColour": self.color_to_dict(self.props.surface_colour),
|
||||||
|
"Transparency": self.props.transparency or None,
|
||||||
|
"ReflectanceMethod": self.props.reflectance_method,
|
||||||
|
"DiffuseColour": diffuse_colour,
|
||||||
|
"SpecularColour": specular_colour,
|
||||||
|
"SpecularHighlight": specular_highlight,
|
||||||
|
}
|
||||||
|
|
||||||
|
def color_to_dict(self, x):
|
||||||
|
return {"Red": x[0], "Green": x[1], "Blue": x[2]}
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ def get_style_types(self, context):
|
|||||||
return StylesData.data["style_types"]
|
return StylesData.data["style_types"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_reflectance_methods(self, context):
|
||||||
|
if not StylesData.is_loaded:
|
||||||
|
StylesData.load()
|
||||||
|
return StylesData.data["reflectance_methods"]
|
||||||
|
|
||||||
|
|
||||||
class Style(PropertyGroup):
|
class Style(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
name: StringProperty(name="Name")
|
||||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||||
@@ -49,6 +55,10 @@ class Style(PropertyGroup):
|
|||||||
surface_colour: bpy.props.FloatVectorProperty(
|
surface_colour: bpy.props.FloatVectorProperty(
|
||||||
name="Surface Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
name="Surface Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
||||||
)
|
)
|
||||||
|
has_diffuse_colour: BoolProperty(name="Has Diffuse Colour", default=False)
|
||||||
|
diffuse_colour: bpy.props.FloatVectorProperty(
|
||||||
|
name="Diffuse Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
STYLE_TYPES = [
|
STYLE_TYPES = [
|
||||||
@@ -91,6 +101,27 @@ class BIMStylesProperties(PropertyGroup):
|
|||||||
name="Surface Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
name="Surface Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
||||||
)
|
)
|
||||||
transparency: bpy.props.FloatProperty(name="Transparency", default=0.0, min=0.0, max=1.0)
|
transparency: bpy.props.FloatProperty(name="Transparency", default=0.0, min=0.0, max=1.0)
|
||||||
|
is_diffuse_colour_null: BoolProperty(name="Is Null")
|
||||||
|
diffuse_colour_class: EnumProperty(
|
||||||
|
items=[(x, x, "") for x in ("IfcColourRgb", "IfcNormalisedRatioMeasure")],
|
||||||
|
name="Diffuse Colour Class",
|
||||||
|
)
|
||||||
|
diffuse_colour: bpy.props.FloatVectorProperty(
|
||||||
|
name="Diffuse Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
||||||
|
)
|
||||||
|
diffuse_colour_ratio: bpy.props.FloatProperty(name="Diffuse Ratio", default=0.0, min=0.0, max=1.0)
|
||||||
|
is_specular_colour_null: BoolProperty(name="Is Null")
|
||||||
|
specular_colour_class: EnumProperty(
|
||||||
|
items=[(x, x, "") for x in ("IfcColourRgb", "IfcNormalisedRatioMeasure")],
|
||||||
|
name="Specular Colour Class",
|
||||||
|
)
|
||||||
|
specular_colour: bpy.props.FloatVectorProperty(
|
||||||
|
name="Specular Colour", subtype="COLOR", default=(1, 1, 1), min=0.0, max=1.0, size=3
|
||||||
|
)
|
||||||
|
specular_colour_ratio: bpy.props.FloatProperty(name="Specular Ratio", default=0.0, min=0.0, max=1.0)
|
||||||
|
is_specular_highlight_null: BoolProperty(name="Is Null")
|
||||||
|
specular_highlight: bpy.props.FloatProperty(name="Specular Highlight", default=0.0, min=0.0, max=1.0)
|
||||||
|
reflectance_method: EnumProperty(name="Reflectance Method", items=get_reflectance_methods)
|
||||||
styles: CollectionProperty(name="Styles", type=Style)
|
styles: CollectionProperty(name="Styles", type=Style)
|
||||||
active_style_index: IntProperty(name="Active Style Index")
|
active_style_index: IntProperty(name="Active Style Index")
|
||||||
active_style_type: EnumProperty(
|
active_style_type: EnumProperty(
|
||||||
|
|||||||
@@ -131,6 +131,55 @@ class BIM_PT_styles(Panel):
|
|||||||
row.prop(self.props, "surface_colour")
|
row.prop(self.props, "surface_colour")
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
row.prop(self.props, "transparency")
|
row.prop(self.props, "transparency")
|
||||||
|
row = self.layout.row()
|
||||||
|
row.prop(self.props, "reflectance_method")
|
||||||
|
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.label(text="Diffuse")
|
||||||
|
row.prop(self.props, "diffuse_colour_class", text="")
|
||||||
|
if self.props.diffuse_colour_class == "IfcColourRgb":
|
||||||
|
row.prop(self.props, "diffuse_colour", text="")
|
||||||
|
else:
|
||||||
|
row.prop(self.props, "diffuse_colour_ratio", text="")
|
||||||
|
row.prop(
|
||||||
|
self.props,
|
||||||
|
"is_diffuse_colour_null",
|
||||||
|
text="",
|
||||||
|
icon="RADIOBUT_OFF" if self.props.is_diffuse_colour_null else "RADIOBUT_ON",
|
||||||
|
)
|
||||||
|
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
if self.props.reflectance_method in ("PHYSICAL", "NOTDEFINED"):
|
||||||
|
row.label(text="Metallic")
|
||||||
|
else:
|
||||||
|
row.label(text="Specular")
|
||||||
|
row.prop(self.props, "specular_colour_class", text="")
|
||||||
|
if self.props.specular_colour_class == "IfcColourRgb":
|
||||||
|
row.prop(self.props, "specular_colour", text="")
|
||||||
|
else:
|
||||||
|
row.prop(self.props, "specular_colour_ratio", text="")
|
||||||
|
row.prop(
|
||||||
|
self.props,
|
||||||
|
"is_specular_colour_null",
|
||||||
|
text="",
|
||||||
|
icon="RADIOBUT_OFF" if self.props.is_specular_colour_null else "RADIOBUT_ON",
|
||||||
|
)
|
||||||
|
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
if self.props.reflectance_method in ("PHYSICAL", "NOTDEFINED"):
|
||||||
|
row.label(text="Roughness")
|
||||||
|
elif self.props.reflectance_method in ("PHONG"):
|
||||||
|
row.label(text="Shininess")
|
||||||
|
else:
|
||||||
|
row.label(text="Highlight")
|
||||||
|
row.prop(self.props, "specular_highlight", text="")
|
||||||
|
row.prop(
|
||||||
|
self.props,
|
||||||
|
"is_specular_highlight_null",
|
||||||
|
text="",
|
||||||
|
icon="RADIOBUT_OFF" if self.props.is_specular_highlight_null else "RADIOBUT_ON",
|
||||||
|
)
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.edit_surface_style", text="Save Rendering Style", icon="CHECKMARK")
|
row.operator("bim.edit_surface_style", text="Save Rendering Style", icon="CHECKMARK")
|
||||||
row.operator("bim.disable_editing_style", text="", icon="CANCEL")
|
row.operator("bim.disable_editing_style", text="", icon="CANCEL")
|
||||||
@@ -285,9 +334,11 @@ class BIM_UL_styles(UIList):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=item.name)
|
row.label(text=item.name)
|
||||||
if item.has_surface_colour:
|
if item.has_surface_colour:
|
||||||
row = row.row()
|
row = row.row(align=True)
|
||||||
row.enabled = False
|
row.enabled = False
|
||||||
row.prop(item, "surface_colour", text="")
|
row.prop(item, "surface_colour", text="")
|
||||||
|
if item.has_diffuse_colour:
|
||||||
|
row.prop(item, "diffuse_colour", text="")
|
||||||
row2 = row.row()
|
row2 = row.row()
|
||||||
row2.alignment = "RIGHT"
|
row2.alignment = "RIGHT"
|
||||||
row2.label(text=str(item.total_elements))
|
row2.label(text=str(item.total_elements))
|
||||||
|
|||||||
@@ -423,6 +423,7 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def import_presentation_styles(cls, style_type):
|
def import_presentation_styles(cls, style_type):
|
||||||
|
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
|
||||||
props = bpy.context.scene.BIMStylesProperties
|
props = bpy.context.scene.BIMStylesProperties
|
||||||
props.styles.clear()
|
props.styles.clear()
|
||||||
styles = sorted(tool.Ifc.get().by_type(style_type), key=lambda x: x.Name or "Unnamed")
|
styles = sorted(tool.Ifc.get().by_type(style_type), key=lambda x: x.Name or "Unnamed")
|
||||||
@@ -435,9 +436,12 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
new2 = new.style_classes.add()
|
new2 = new.style_classes.add()
|
||||||
new2.name = surface_style.is_a()
|
new2.name = surface_style.is_a()
|
||||||
if surface_style.is_a("IfcSurfaceStyleShading"):
|
if surface_style.is_a("IfcSurfaceStyleShading"):
|
||||||
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
|
|
||||||
new.has_surface_colour = True
|
new.has_surface_colour = True
|
||||||
new.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
new.surface_colour = color_to_tuple(surface_style.SurfaceColour)
|
||||||
|
if surface_style.is_a("IfcSurfaceStyleRendering"):
|
||||||
|
if surface_style.DiffuseColour and surface_style.DiffuseColour.is_a("IfcColourRgb"):
|
||||||
|
new.has_diffuse_colour = True
|
||||||
|
new.diffuse_colour = color_to_tuple(surface_style.DiffuseColour)
|
||||||
new.total_elements = len(ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style))
|
new.total_elements = len(ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import ifcopenshell.util.selector
|
|||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
def __init__(self, src, file, logger, query: str = ".IfcWall"):
|
def __init__(self, src, file, logger, query: str = "IfcWall"):
|
||||||
"""Extract certain elements into a new model
|
"""Extract certain elements into a new model
|
||||||
|
|
||||||
Extract a subset of elements from an existing IFC data set and save it
|
Extract a subset of elements from an existing IFC data set and save it
|
||||||
|
|||||||
Reference in New Issue
Block a user