mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 19:36:21 +00:00
Refactor Standalone section shader (#2172)
* Refactor Standalone section shader * Remove leftover code
This commit is contained in:
@@ -13,11 +13,9 @@ bl_info = {
|
|||||||
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.types import Operator
|
from bpy.types import Operator, PropertyGroup, Panel
|
||||||
from bpy.props import FloatVectorProperty
|
|
||||||
from mathutils import Vector, Matrix, Euler
|
from mathutils import Vector, Matrix, Euler
|
||||||
from math import radians
|
from math import radians
|
||||||
from bpy.types import PropertyGroup
|
|
||||||
from bpy.props import (
|
from bpy.props import (
|
||||||
PointerProperty,
|
PointerProperty,
|
||||||
StringProperty,
|
StringProperty,
|
||||||
@@ -30,62 +28,131 @@ from bpy.props import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_section_color(self, context):
|
class SectionCutawayManager:
|
||||||
section_node_group = bpy.data.node_groups.get("Section Override")
|
@staticmethod
|
||||||
if section_node_group is None:
|
def get_section_tree():
|
||||||
return
|
return bpy.data.node_groups.get("Section Override")
|
||||||
try:
|
|
||||||
emission_node = next(n for n in section_node_group.nodes if isinstance(n, bpy.types.ShaderNodeEmission))
|
|
||||||
emission_node.inputs[0].default_value = list(self.section_plane_colour) + [1]
|
|
||||||
except StopIteration:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_sections_map():
|
||||||
|
section_tree = SectionCutawayManager.get_section_tree()
|
||||||
|
return {n: n.object for n in section_tree.nodes if isinstance(n, bpy.types.ShaderNodeTexCoord)}
|
||||||
|
|
||||||
class BIM_OT_add_section_plane(bpy.types.Operator):
|
@staticmethod
|
||||||
"""Add a temporary empty object as a section cutaway. Cull all geometry rendering below the empty's local Z axis"""
|
def purge_all_section_data():
|
||||||
|
section_override_mat = bpy.data.materials.get("Section Override")
|
||||||
|
if section_override_mat:
|
||||||
|
bpy.data.materials.remove(section_override_mat)
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
if not material.node_tree:
|
||||||
|
continue
|
||||||
|
override = material.node_tree.nodes.get("Section Override")
|
||||||
|
if not override:
|
||||||
|
continue
|
||||||
|
material.node_tree.links.new(
|
||||||
|
override.inputs[0].links[0].from_socket, override.outputs[0].links[0].to_socket
|
||||||
|
)
|
||||||
|
material.node_tree.nodes.remove(override)
|
||||||
|
bpy.data.node_groups.remove(SectionCutawayManager.get_section_tree())
|
||||||
|
bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Compare"))
|
||||||
|
|
||||||
bl_idname = "bim.add_section_plane"
|
@staticmethod
|
||||||
bl_label = "Add Temporary Section Cutaway"
|
def clean():
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
sections_map = SectionCutawayManager.get_sections_map()
|
||||||
|
sections_map_iterator = list(sections_map.items())
|
||||||
|
for tex_coord_node, section_obj in sections_map_iterator:
|
||||||
|
if section_obj is None or section_obj.users == 1:
|
||||||
|
SectionCutawayManager.unplug(tex_coord_node)
|
||||||
|
sections_map.pop(tex_coord_node)
|
||||||
|
if not any(o for o in sections_map.values() if o.users > 1):
|
||||||
|
SectionCutawayManager.purge_all_section_data()
|
||||||
|
|
||||||
def execute(self, context):
|
@staticmethod
|
||||||
obj = self.create_section_obj(context)
|
def unplug(tex_coords):
|
||||||
if not self.has_section_override_node():
|
section_tree = SectionCutawayManager.get_section_tree()
|
||||||
self.create_section_compare_node()
|
section_compare = tex_coords.outputs["Object"].links[0].to_node
|
||||||
self.create_section_override_node(obj, context)
|
if section_compare.inputs[0].links:
|
||||||
else:
|
previous_section_compare = section_compare.inputs[0].links[0].from_node
|
||||||
self.append_obj_to_section_override_node(obj)
|
next_section_compare = section_compare.outputs[0].links[0].to_node
|
||||||
self.add_default_material_if_none_exists(context)
|
section_tree.links.new(previous_section_compare.outputs[0], next_section_compare.inputs[0])
|
||||||
self.override_materials()
|
SectionCutawayManager.offset_previous_nodes(section_compare, offset_x=200)
|
||||||
return {"FINISHED"}
|
section_tree.nodes.remove(section_compare)
|
||||||
|
section_tree.nodes.remove(tex_coords)
|
||||||
|
|
||||||
def create_section_obj(self, context):
|
@staticmethod
|
||||||
|
def offset_previous_nodes(section_compare, offset_x=0, offset_y=0):
|
||||||
|
if section_compare.inputs[0].links:
|
||||||
|
previous_section_compare = section_compare.inputs[0].links[0].from_node
|
||||||
|
previous_section_compare.location += Vector((offset_x, offset_y))
|
||||||
|
if previous_section_compare.inputs[1].links:
|
||||||
|
previous_section_compare.inputs[1].links[0].from_node.location += Vector((offset_x, offset_y))
|
||||||
|
SectionCutawayManager.offset_previous_nodes(previous_section_compare, offset_x, offset_y)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def override_materials():
|
||||||
|
override = SectionCutawayManager.get_section_tree()
|
||||||
|
for material in bpy.data.materials:
|
||||||
|
material.use_nodes = True
|
||||||
|
if material.node_tree.nodes.get(override.name):
|
||||||
|
continue
|
||||||
|
material.blend_method = "HASHED"
|
||||||
|
material.shadow_method = "HASHED"
|
||||||
|
material_output = next((n for n in material.node_tree.nodes if n.type == "OUTPUT_MATERIAL"), None)
|
||||||
|
if material_output is None:
|
||||||
|
continue
|
||||||
|
from_socket = material_output.inputs[0].links[0].from_socket
|
||||||
|
section_override = material.node_tree.nodes.new(type="ShaderNodeGroup")
|
||||||
|
section_override.name = "Section Override"
|
||||||
|
section_override.node_tree = override
|
||||||
|
material.node_tree.links.new(from_socket, section_override.inputs[0])
|
||||||
|
material.node_tree.links.new(section_override.outputs[0], material_output.inputs[0])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_section_obj(from_obj, scene):
|
||||||
section = bpy.data.objects.new("Section", None)
|
section = bpy.data.objects.new("Section", None)
|
||||||
section.empty_display_type = "SINGLE_ARROW"
|
section.empty_display_type = "SINGLE_ARROW"
|
||||||
section.empty_display_size = 5
|
section.empty_display_size = 5
|
||||||
section.show_in_front = True
|
section.show_in_front = True
|
||||||
if (
|
if from_obj and from_obj.select_get() and isinstance(from_obj.data, bpy.types.Camera):
|
||||||
context.active_object
|
section.matrix_world = from_obj.matrix_world @ Euler((radians(180.0), 0.0, 0.0), "XYZ").to_matrix().to_4x4()
|
||||||
and context.active_object.select_get()
|
|
||||||
and isinstance(context.active_object.data, bpy.types.Camera)
|
|
||||||
):
|
|
||||||
section.matrix_world = (
|
|
||||||
context.active_object.matrix_world @ Euler((radians(180.0), 0.0, 0.0), "XYZ").to_matrix().to_4x4()
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
section.rotation_euler = Euler((radians(180.0), 0.0, 0.0), "XYZ")
|
section.rotation_euler = Euler((radians(180.0), 0.0, 0.0), "XYZ")
|
||||||
section.location = context.scene.cursor.location
|
section.location = scene.cursor.location
|
||||||
collection = bpy.data.collections.get("Sections")
|
collection = bpy.data.collections.get("Sections")
|
||||||
if not collection:
|
if not collection:
|
||||||
collection = bpy.data.collections.new("Sections")
|
collection = bpy.data.collections.new("Sections")
|
||||||
context.scene.collection.children.link(collection)
|
scene.collection.children.link(collection)
|
||||||
collection.objects.link(section)
|
collection.objects.link(section)
|
||||||
return section
|
return section
|
||||||
|
|
||||||
def has_section_override_node(self):
|
@classmethod
|
||||||
return bpy.data.node_groups.get("Section Override")
|
def add_section_plane(cls, context):
|
||||||
|
obj = cls.create_section_obj(context.active_object, context.scene)
|
||||||
|
if cls.get_section_tree() is not None:
|
||||||
|
cls.append_obj_to_section_override_node(obj)
|
||||||
|
else:
|
||||||
|
cls.create_section_compare_node()
|
||||||
|
cls.create_section_override_node(obj, context)
|
||||||
|
cls.add_default_material_if_none_exists(context)
|
||||||
|
cls.override_materials()
|
||||||
|
|
||||||
def create_section_compare_node(self):
|
@classmethod
|
||||||
|
def remove_all_section_planes(cls):
|
||||||
|
objs = [o for o in cls.get_sections_map().values() if o is not None]
|
||||||
|
cls.remove_section_planes(objs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_section_planes(cls, objects):
|
||||||
|
sections_map = cls.get_sections_map()
|
||||||
|
for obj in objects:
|
||||||
|
tex_coords = next((n for n in sections_map if sections_map[n] == obj), None)
|
||||||
|
if tex_coords is not None:
|
||||||
|
cls.unplug(tex_coords)
|
||||||
|
sections_map.pop(tex_coords)
|
||||||
|
bpy.data.objects.remove(obj)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_section_compare_node():
|
||||||
group = bpy.data.node_groups.new("Section Compare", type="ShaderNodeTree")
|
group = bpy.data.node_groups.new("Section Compare", type="ShaderNodeTree")
|
||||||
group_input = group.nodes.new(type="NodeGroupInput")
|
group_input = group.nodes.new(type="NodeGroupInput")
|
||||||
group_input.location = 0, 50
|
group_input.location = 0, 50
|
||||||
@@ -112,7 +179,8 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
|
|||||||
group.links.new(greater.outputs[0], multiply.inputs[1])
|
group.links.new(greater.outputs[0], multiply.inputs[1])
|
||||||
group.links.new(multiply.outputs[0], group_output.inputs[""])
|
group.links.new(multiply.outputs[0], group_output.inputs[""])
|
||||||
|
|
||||||
def create_section_override_node(self, obj, context):
|
@staticmethod
|
||||||
|
def create_section_override_node(obj, context):
|
||||||
group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree")
|
group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree")
|
||||||
links = group.links
|
links = group.links
|
||||||
nodes = group.nodes
|
nodes = group.nodes
|
||||||
@@ -121,45 +189,53 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
|
|||||||
group_output = nodes.new(type="NodeGroupOutput")
|
group_output = nodes.new(type="NodeGroupOutput")
|
||||||
group_output.location = 600, 250
|
group_output.location = 600, 250
|
||||||
|
|
||||||
|
hide_mix = group.nodes.new(type="ShaderNodeMixShader")
|
||||||
|
hide_mix.name = "Hide Mix"
|
||||||
|
hide_mix.inputs[0].default_value = 0
|
||||||
|
hide_mix.location = group_output.location - Vector((200, 0))
|
||||||
|
|
||||||
backfacing_mix = nodes.new(type="ShaderNodeMixShader")
|
backfacing_mix = nodes.new(type="ShaderNodeMixShader")
|
||||||
backfacing_mix.location = group_output.location - Vector((400, 350))
|
backfacing_mix.location = group_output.location - Vector((600, 350))
|
||||||
|
|
||||||
backfacing = nodes.new(type="ShaderNodeNewGeometry")
|
backfacing = nodes.new(type="ShaderNodeNewGeometry")
|
||||||
backfacing.location = backfacing_mix.location + Vector((-200, 200))
|
backfacing.location = backfacing_mix.location + Vector((-400, 200))
|
||||||
group_input.location = backfacing_mix.location - Vector((200, 50))
|
group_input.location = backfacing_mix.location - Vector((400, 50))
|
||||||
|
|
||||||
emission = nodes.new(type="ShaderNodeEmission")
|
emission = nodes.new(type="ShaderNodeEmission")
|
||||||
emission.inputs[0].default_value = list(context.scene.SectionProperties.section_plane_colour) + [1]
|
emission.inputs[0].default_value = list(context.scene.SectionProperties.section_plane_colour) + [1]
|
||||||
emission.location = backfacing_mix.location - Vector((200, 150))
|
emission.location = backfacing_mix.location - Vector((400, 150))
|
||||||
|
|
||||||
transparent = nodes.new(type="ShaderNodeBsdfTransparent")
|
transparent = nodes.new(type="ShaderNodeBsdfTransparent")
|
||||||
transparent.location = group_output.location - Vector((400, 100))
|
transparent.location = group_output.location - Vector((600, 100))
|
||||||
|
|
||||||
section_mix = group.nodes.new(type="ShaderNodeMixShader")
|
section_mix = group.nodes.new(type="ShaderNodeMixShader")
|
||||||
section_mix.name = "Section Mix"
|
section_mix.name = "Section Mix"
|
||||||
section_mix.inputs[0].default_value = 1 # Directly pass input shader when there is no cutaway
|
section_mix.inputs[0].default_value = 1 # Directly pass input shader when there is no cutaway
|
||||||
section_mix.location = group_output.location - Vector((200, 0))
|
section_mix.location = group_output.location - Vector((400, 0))
|
||||||
|
|
||||||
cut_obj = nodes.new(type="ShaderNodeTexCoord")
|
cut_obj = nodes.new(type="ShaderNodeTexCoord")
|
||||||
cut_obj.object = obj
|
cut_obj.object = obj
|
||||||
cut_obj.location = group_output.location - Vector((800, 150))
|
cut_obj.location = group_output.location - Vector((1000, 150))
|
||||||
|
|
||||||
section_compare = nodes.new(type="ShaderNodeGroup")
|
section_compare = nodes.new(type="ShaderNodeGroup")
|
||||||
section_compare.node_tree = bpy.data.node_groups.get("Section Compare")
|
section_compare.node_tree = bpy.data.node_groups.get("Section Compare")
|
||||||
section_compare.name = "Last Section Compare"
|
section_compare.name = "Last Section Compare"
|
||||||
section_compare.location = group_output.location - Vector((600, 0))
|
section_compare.location = group_output.location - Vector((800, 0))
|
||||||
|
|
||||||
links.new(cut_obj.outputs["Object"], section_compare.inputs[1])
|
links.new(cut_obj.outputs["Object"], section_compare.inputs[1])
|
||||||
links.new(backfacing.outputs["Backfacing"], backfacing_mix.inputs[0])
|
links.new(backfacing.outputs["Backfacing"], backfacing_mix.inputs[0])
|
||||||
links.new(group_input.outputs[""], backfacing_mix.inputs[1])
|
links.new(group_input.outputs[""], backfacing_mix.inputs[1])
|
||||||
links.new(emission.outputs["Emission"], backfacing_mix.inputs[2])
|
links.new(emission.outputs["Emission"], backfacing_mix.inputs[2])
|
||||||
links.new(section_compare.outputs[0], section_mix.inputs[0])
|
links.new(section_compare.outputs[0], section_mix.inputs[0])
|
||||||
links.new(transparent.outputs["BSDF"], section_mix.inputs[1])
|
links.new(transparent.outputs[0], section_mix.inputs[1])
|
||||||
links.new(backfacing_mix.outputs["Shader"], section_mix.inputs[2])
|
links.new(backfacing_mix.outputs[0], section_mix.inputs[2])
|
||||||
links.new(section_mix.outputs["Shader"], group_output.inputs[""])
|
links.new(section_mix.outputs[0], hide_mix.inputs[1])
|
||||||
|
links.new(group_input.outputs["Shader"], hide_mix.inputs[2])
|
||||||
|
links.new(hide_mix.outputs[0], group_output.inputs[""])
|
||||||
|
|
||||||
def append_obj_to_section_override_node(self, obj):
|
@staticmethod
|
||||||
group = bpy.data.node_groups.get("Section Override")
|
def append_obj_to_section_override_node(obj):
|
||||||
|
group = SectionCutawayManager.get_section_tree()
|
||||||
try:
|
try:
|
||||||
last_section_node = next(
|
last_section_node = next(
|
||||||
n
|
n
|
||||||
@@ -185,7 +261,8 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
|
|||||||
|
|
||||||
section_compare.name = "Last Section Compare"
|
section_compare.name = "Last Section Compare"
|
||||||
|
|
||||||
def add_default_material_if_none_exists(self, context):
|
@staticmethod
|
||||||
|
def add_default_material_if_none_exists(context):
|
||||||
material = bpy.data.materials.get("Section Override")
|
material = bpy.data.materials.get("Section Override")
|
||||||
if not material:
|
if not material:
|
||||||
material = bpy.data.materials.new("Section Override")
|
material = bpy.data.materials.new("Section Override")
|
||||||
@@ -208,92 +285,74 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
obj.data.materials.append(material)
|
obj.data.materials.append(material)
|
||||||
|
|
||||||
def override_materials(self):
|
|
||||||
override = bpy.data.node_groups.get("Section Override")
|
|
||||||
for material in bpy.data.materials:
|
|
||||||
material.use_nodes = True
|
|
||||||
if material.node_tree.nodes.get("Section Override"):
|
|
||||||
continue
|
|
||||||
material.blend_method = "HASHED"
|
|
||||||
material.shadow_method = "HASHED"
|
|
||||||
material_output = self.get_node(material.node_tree.nodes, "OUTPUT_MATERIAL")
|
|
||||||
if not material_output:
|
|
||||||
continue
|
|
||||||
from_socket = material_output.inputs[0].links[0].from_socket
|
|
||||||
section_override = material.node_tree.nodes.new(type="ShaderNodeGroup")
|
|
||||||
section_override.name = "Section Override"
|
|
||||||
section_override.node_tree = override
|
|
||||||
material.node_tree.links.new(from_socket, section_override.inputs[0])
|
|
||||||
material.node_tree.links.new(section_override.outputs[0], material_output.inputs[0])
|
|
||||||
|
|
||||||
def get_node(self, nodes, node_type):
|
class BIM_OT_section_plane_refresh(Operator):
|
||||||
for node in nodes:
|
bl_idname = "bim.section_plane_refresh"
|
||||||
if node.type == node_type:
|
bl_label = "Refresh Section Cutaway Shader"
|
||||||
return node
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
update_visibility(None, context)
|
||||||
|
SectionCutawayManager.add_default_material_if_none_exists(context)
|
||||||
|
SectionCutawayManager.clean()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class BIM_OT_remove_section_plane(bpy.types.Operator):
|
class BIM_OT_section_plane_add(Operator):
|
||||||
"""Remove selected section plane. No effect if executed on a regular object"""
|
"""Add a temporary empty object as a section cutaway. Cull all geometry rendering below the empty's local Z axis"""
|
||||||
|
|
||||||
bl_idname = "bim.remove_section_plane"
|
bl_idname = "bim.section_plane_add"
|
||||||
|
bl_label = "Add Temporary Section Cutaway"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
SectionCutawayManager.add_section_plane(context)
|
||||||
|
SectionCutawayManager.clean()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_OT_section_plane_remove(Operator):
|
||||||
|
bl_idname = "bim.section_plane_remove"
|
||||||
bl_label = "Remove Temporary Section Cutaway"
|
bl_label = "Remove Temporary Section Cutaway"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
bl_description = "Remove section planes. No effect if executed on a regular object"
|
||||||
|
remove_all: BoolProperty(default=False, options={"HIDDEN"})
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return context.active_object and bpy.data.node_groups.get("Section Override")
|
return SectionCutawayManager.get_section_tree() is not None
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
name = context.active_object.name
|
if self.remove_all:
|
||||||
section_override = bpy.data.node_groups.get("Section Override")
|
SectionCutawayManager.remove_all_section_planes()
|
||||||
tex_coords = next(
|
else:
|
||||||
(
|
SectionCutawayManager.remove_section_planes(context.selected_objects)
|
||||||
n
|
SectionCutawayManager.clean()
|
||||||
for n in section_override.nodes
|
|
||||||
if isinstance(n, bpy.types.ShaderNodeTexCoord) and n.object.name == name
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
if tex_coords is not None:
|
|
||||||
section_compare = tex_coords.outputs["Object"].links[0].to_node
|
|
||||||
if section_compare.inputs[0].links:
|
|
||||||
previous_section_compare = section_compare.inputs[0].links[0].from_node
|
|
||||||
next_section_compare = section_compare.outputs[0].links[0].to_node
|
|
||||||
section_override.links.new(previous_section_compare.outputs[0], next_section_compare.inputs[0])
|
|
||||||
self.offset_previous_nodes(section_compare, offset_x=200)
|
|
||||||
section_override.nodes.remove(section_compare)
|
|
||||||
section_override.nodes.remove(tex_coords)
|
|
||||||
bpy.data.objects.remove(context.active_object)
|
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def offset_previous_nodes(self, section_compare, offset_x=0, offset_y=0):
|
|
||||||
if section_compare.inputs[0].links:
|
|
||||||
previous_section_compare = section_compare.inputs[0].links[0].from_node
|
|
||||||
previous_section_compare.location += Vector((offset_x, offset_y))
|
|
||||||
if previous_section_compare.inputs[1].links:
|
|
||||||
previous_section_compare.inputs[1].links[0].from_node.location += Vector((offset_x, offset_y))
|
|
||||||
self.offset_previous_nodes(previous_section_compare, offset_x, offset_y)
|
|
||||||
|
|
||||||
def purge_all_section_data(self, context):
|
def update_visibility(self, context):
|
||||||
bpy.data.materials.remove(bpy.data.materials.get("Section Override"))
|
tree = SectionCutawayManager.get_section_tree()
|
||||||
for material in bpy.data.materials:
|
if tree:
|
||||||
if not material.node_tree:
|
node = tree.nodes.get("Hide Mix")
|
||||||
continue
|
if node:
|
||||||
override = material.node_tree.nodes.get("Section Override")
|
node.inputs[0].default_value = int(context.scene.SectionProperties.hide)
|
||||||
if not override:
|
|
||||||
continue
|
|
||||||
material.node_tree.links.new(
|
def update_section_color(self, context):
|
||||||
override.inputs[0].links[0].from_socket, override.outputs[0].links[0].to_socket
|
section_node_group = SectionCutawayManager.get_section_tree()
|
||||||
)
|
if section_node_group is None:
|
||||||
material.node_tree.nodes.remove(override)
|
return
|
||||||
bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Override"))
|
try:
|
||||||
bpy.data.node_groups.remove(bpy.data.node_groups.get("Section Compare"))
|
emission_node = next(n for n in section_node_group.nodes if isinstance(n, bpy.types.ShaderNodeEmission))
|
||||||
bpy.ops.object.delete({"selected_objects": [context.active_object]})
|
emission_node.inputs[0].default_value = list(self.section_plane_colour) + [1]
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SectionProperties(PropertyGroup):
|
class SectionProperties(PropertyGroup):
|
||||||
should_section_selected_objects: BoolProperty(name="Section Selected Objects", default=False)
|
should_section_selected_objects: BoolProperty(name="Section Selected Objects", default=False)
|
||||||
|
hide: BoolProperty(default=False, name="Toggle", update=update_visibility)
|
||||||
section_plane_colour: FloatVectorProperty(
|
section_plane_colour: FloatVectorProperty(
|
||||||
name="Temporary Section Cutaway Colour",
|
name="Temporary Section Cutaway Colour",
|
||||||
subtype="COLOR",
|
subtype="COLOR",
|
||||||
@@ -304,7 +363,7 @@ class SectionProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_section_plane(bpy.types.Panel):
|
class BIM_PT_section_plane(Panel):
|
||||||
bl_label = "Temporary Section Cutaways"
|
bl_label = "Temporary Section Cutaways"
|
||||||
bl_idname = "BIM_PT_section_plane"
|
bl_idname = "BIM_PT_section_plane"
|
||||||
bl_space_type = "VIEW_3D"
|
bl_space_type = "VIEW_3D"
|
||||||
@@ -316,30 +375,31 @@ class BIM_PT_section_plane(bpy.types.Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
props = context.scene.SectionProperties
|
props = context.scene.SectionProperties
|
||||||
|
|
||||||
row = layout.row()
|
layout.prop(props, "should_section_selected_objects", text="Only Selected", icon="RESTRICT_SELECT_OFF")
|
||||||
row.prop(props, "should_section_selected_objects")
|
layout.prop(props, "section_plane_colour", text="Section Color")
|
||||||
|
layout.prop(props, "hide", icon="HIDE_ON" if props.hide else "HIDE_OFF")
|
||||||
|
|
||||||
row = layout.row()
|
layout.operator("bim.section_plane_refresh", text="Refresh", icon="FILE_REFRESH")
|
||||||
row.prop(props, "section_plane_colour")
|
layout.operator("bim.section_plane_add", text="Add Section Cutaway", icon="ADD")
|
||||||
|
layout.operator("bim.section_plane_remove", text="Remove Selected Sections", icon="REMOVE").remove_all = False
|
||||||
row = layout.row(align=True)
|
layout.operator("bim.section_plane_remove", text="Remove All Sections", icon="TRASH").remove_all = True
|
||||||
row.operator("bim.add_section_plane")
|
|
||||||
row.operator("bim.remove_section_plane")
|
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SectionProperties)
|
bpy.utils.register_class(SectionProperties)
|
||||||
bpy.utils.register_class(BIM_OT_add_section_plane)
|
bpy.utils.register_class(BIM_OT_section_plane_add)
|
||||||
bpy.utils.register_class(BIM_OT_remove_section_plane)
|
bpy.utils.register_class(BIM_OT_section_plane_remove)
|
||||||
bpy.utils.register_class(BIM_PT_section_plane)
|
bpy.utils.register_class(BIM_PT_section_plane)
|
||||||
bpy.types.Scene.SectionProperties = bpy.props.PointerProperty(type=SectionProperties)
|
bpy.utils.register_class(BIM_OT_section_plane_refresh)
|
||||||
|
bpy.types.Scene.SectionProperties = PointerProperty(type=SectionProperties)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(BIM_OT_add_section_plane)
|
bpy.utils.unregister_class(BIM_OT_section_plane_add)
|
||||||
bpy.utils.unregister_class(BIM_OT_remove_section_plane)
|
bpy.utils.unregister_class(BIM_OT_section_plane_remove)
|
||||||
bpy.utils.unregister_class(BIM_PT_section_plane)
|
bpy.utils.unregister_class(BIM_PT_section_plane)
|
||||||
bpy.utils.unregister_class(SectionProperties)
|
bpy.utils.unregister_class(SectionProperties)
|
||||||
|
bpy.utils.unregister_class(BIM_OT_section_plane_refresh)
|
||||||
del bpy.types.Scene.SectionProperties
|
del bpy.types.Scene.SectionProperties
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user