119 lines
3.4 KiB
Python
119 lines
3.4 KiB
Python
# Copyright 2015 Théo Friberg under GNU GPL 3
|
|
|
|
if "bpy" in locals():
|
|
import importlib
|
|
importlib.reload(JSONOps)
|
|
else:
|
|
from . import JSONOps
|
|
|
|
import bpy
|
|
import os
|
|
|
|
class AdjustableOperatorFromTexture(bpy.types.Operator):
|
|
"""
|
|
This operator generates adjustable materials from textures in Cycles.
|
|
This is a subclass from bpy.types.Operator.
|
|
"""
|
|
|
|
# Metadata of the operator
|
|
|
|
bl_idname = "com.new_adj_automat"
|
|
bl_label = "Adjustable Material from Image"
|
|
bl_options = {"UNDO"}
|
|
|
|
# Variables used for storing the filepath given by blender's file manager
|
|
|
|
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
|
filename: bpy.props.StringProperty()
|
|
directory: bpy.props.StringProperty(subtype="FILE_PATH")
|
|
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
"""
|
|
This is the main runnable method of the operator.
|
|
This creates all the node setup.
|
|
"""
|
|
|
|
# Create the material
|
|
|
|
mat = bpy.data.materials.new("Material")
|
|
|
|
mat.use_nodes = True
|
|
nodes = mat.node_tree.nodes
|
|
|
|
# Empty whatever nodes we allready had.
|
|
|
|
for node in nodes.keys():
|
|
nodes.remove(nodes[node])
|
|
|
|
nodes_dict = {}
|
|
|
|
# Create the main part of the material
|
|
|
|
nodes_dict = JSONOps.inflateFile(mat, os.path.dirname(
|
|
os.path.realpath(__file__))+os.sep+
|
|
"adj_material.json")
|
|
|
|
# We create all of our blurs
|
|
|
|
blurs = [
|
|
|
|
JSONOps.inflateFile(mat, os.path.dirname(os.path.realpath(__file__))+
|
|
os.sep+"blur.json", -2500, -300),
|
|
JSONOps.inflateFile(mat, os.path.dirname(os.path.realpath(__file__))+
|
|
os.sep+"blur.json", -2300, 300)
|
|
]
|
|
|
|
# We set one of our blurs to be stronger
|
|
|
|
blurs[1]["Blur strength"].outputs[0].default_value = 1000
|
|
|
|
# We link the blurs up to the rest of the material
|
|
|
|
links = mat.node_tree.links
|
|
|
|
links.new(blurs[1]["Correct strength vector math"].outputs[0],
|
|
nodes_dict["Greater Than"].inputs[0])
|
|
links.new(blurs[0]["Correct strength vector math"].outputs[0],
|
|
nodes_dict["Bumpmap Mix RGB"].inputs[2])
|
|
links.new(nodes_dict["Texture Co-ordinate"].outputs["UV"],
|
|
blurs[0]["Add noise"].inputs[0])
|
|
|
|
# We load the images
|
|
|
|
image_data = bpy.data.images.load(self.filepath)
|
|
nodes_dict["Color Image"].image = image_data
|
|
nodes_dict["Bump Image"].image = image_data
|
|
|
|
# Try to add the material to the selected object
|
|
|
|
try:
|
|
bpy.context.object.data.materials.append(mat)
|
|
except AttributeError:
|
|
|
|
# If there is no object with materials selected,
|
|
# don't add the material to anythinng.
|
|
|
|
pass
|
|
|
|
# Tell that all went well
|
|
|
|
return {"FINISHED"}
|
|
|
|
def invoke(self, context, event):
|
|
"""
|
|
This method opens the file browser. After that, the
|
|
execute(...) method gets ran, creating the node setup.
|
|
It also checks that the render engine is Cycles.
|
|
"""
|
|
|
|
if bpy.context.scene.render.engine == 'CYCLES':
|
|
self.filename = ""
|
|
context.window_manager.fileselect_add(self)
|
|
return {"RUNNING_MODAL"}
|
|
else:
|
|
self.report({'ERROR'}, "Can't generate Cycles material with Blender internal as active renderer.")
|
|
return {"FINISHED"}
|