Skip to content

Instantly share code, notes, and snippets.

@Theverat
Last active December 11, 2020 20:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Theverat/f2687c86511ca9c133cec8b93a1e6309 to your computer and use it in GitHub Desktop.
Save Theverat/f2687c86511ca9c133cec8b93a1e6309 to your computer and use it in GitHub Desktop.
"""
An addon that can create LuxCore imagemap nodes from Cycles materials.
Installation: https://docs.blender.org/manual/en/dev/preferences/addons.html#header
Or copy into a text editor and click "Run Script".
The addon adds a button called "Create Image Nodes" in the properties window, scene tab.
"""
import bpy
import bl_ui
bl_info = {
"name": "LuxCore Extras",
"author": "Simon Wendsche (B.Y.O.B.)",
"category": "Render",
"location": "Properties > Scene",
"blender": (2, 80, 0),
}
executed = False
mats_converted = 0
image_nodes_created = 0
def init_mat_node_tree(node_tree):
# Seems like we still need this.
# User counting does not work reliably with Python PointerProperty.
# Sometimes, the material this tree is linked to is not counted as user.
node_tree.use_fake_user = True
nodes = node_tree.nodes
output = nodes.new("LuxCoreNodeMatOutput")
output.location = 300, 200
output.select = False
matte = nodes.new("LuxCoreNodeMatMatte")
matte.location = 50, 200
node_tree.links.new(matte.outputs[0], output.inputs[0])
class LUXCORE_EXTRAS_OT_create_image_nodes(bpy.types.Operator):
bl_idname = "luxcore_extras.create_image_nodes"
bl_label = "Create Image Nodes"
bl_description = ("Iterate all materials in bpy.data, create luxcore node trees if not already there, "
"and create an imagemap node for every Cycles image node in the material")
def execute(self, context):
global mats_converted
global image_nodes_created
mats_converted = 0
image_nodes_created = 0
for mat in bpy.data.materials:
if mat.luxcore.node_tree is None:
node_tree = bpy.data.node_groups.new(name=mat.name, type="luxcore_material_nodes")
mat.luxcore.node_tree = node_tree
init_mat_node_tree(node_tree)
else:
node_tree = mat.luxcore.node_tree
if not mat.node_tree:
# Material does not have a Cycles node tree, skip it
continue
mats_converted += 1
cycles_nodes = mat.node_tree.nodes
xPos = 0
yPos = 0
spacing = 10
for cycles_node in cycles_nodes:
if cycles_node.bl_idname == "ShaderNodeTexImage":
# Check if this image node already exists in the LuxCore node tree
skip = False
for node in node_tree.nodes:
if node.bl_idname == "LuxCoreNodeTexImagemap" and node.image == cycles_node.image:
skip = True
break
if skip:
continue
img_node = node_tree.nodes.new("LuxCoreNodeTexImagemap")
img_node.location = xPos, yPos
yPos += img_node.height + spacing
img_node.image = cycles_node.image
image_nodes_created += 1
global executed
executed = True
return {"FINISHED"}
class LUXCORE_EXTRAS_PT_scene(bl_ui.properties_scene.SceneButtonsPanel, bpy.types.Panel):
bl_label = "LuxCore Extras"
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
return engine == "LUXCORE"
def draw(self, context):
layout = self.layout
layout.operator("luxcore_extras.create_image_nodes")
if executed:
col = layout.column()
col.label("Done.", icon="INFO")
col.label("Processed %d materials" % mats_converted)
col.label("Created %d image nodes" % image_nodes_created)
def register():
bpy.utils.register_class(LUXCORE_EXTRAS_OT_create_image_nodes)
bpy.utils.register_class(LUXCORE_EXTRAS_PT_scene)
def unregister():
bpy.utils.register_class(LUXCORE_EXTRAS_OT_create_image_nodes)
bpy.utils.unregister_class(LUXCORE_EXTRAS_PT_scene)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment