Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'materials_utils/material_converter.py')
-rw-r--r--materials_utils/material_converter.py793
1 files changed, 0 insertions, 793 deletions
diff --git a/materials_utils/material_converter.py b/materials_utils/material_converter.py
deleted file mode 100644
index 3a208e80..00000000
--- a/materials_utils/material_converter.py
+++ /dev/null
@@ -1,793 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import bpy
-import math
-from mathutils import Vector
-from bpy.types import Operator
-from .warning_messages_utils import (
- warning_messages,
- c_is_cycles_addon_enabled,
- c_data_has_materials,
- collect_report,
-)
-
-# -----------------------------------------------------------------------------
-# Globals
-
-nodesDictionary = None
-
-NODE_FRAME = 'NodeFrame'
-BI_MATERIAL_NODE = 'ShaderNodeMaterial'
-BI_OUTPUT_NODE = 'ShaderNodeOutput'
-TEXTURE_IMAGE_NODE = 'ShaderNodeTexImage'
-OUTPUT_NODE = 'ShaderNodeOutputMaterial'
-RGB_MIX_NODE = 'ShaderNodeMixRGB'
-MAPPING_NODE = 'ShaderNodeMapping'
-NORMAL_MAP_NODE = 'ShaderNodeNormalMap'
-SHADER_MIX_NODE = 'ShaderNodeMixShader'
-SHADER_ADD_NODE = 'ShaderNodeAddShader'
-COORD_NODE = 'ShaderNodeTexCoord'
-RGB_TO_BW_NODE = 'ShaderNodeRGBToBW'
-BSDF_DIFFUSE_NODE = 'ShaderNodeBsdfDiffuse'
-BSDF_EMISSION_NODE = 'ShaderNodeEmission'
-BSDF_TRANSPARENT_NODE = 'ShaderNodeBsdfTransparent'
-BSDF_GLOSSY_NODE = 'ShaderNodeBsdfGlossy'
-BSDF_GLASS_NODE = 'ShaderNodeBsdfGlass'
-
-textureNodeSizeX = 150
-textureNodeSizeY = 350
-
-
-# -----------------------------------------------------------------------------
-# Functions
-
-def makeTextureNodeDict(cmat):
- global nodesDictionary
- nodesDictionary = {}
- textures = {textureSlot.texture for textureSlot in cmat.texture_slots if textureSlot}
-
- for tex in textures:
- texNode = None
- if tex.type == 'IMAGE':
- texNode = makeNodeUsingImage1(cmat, tex)
- if texNode:
- nodesDictionary[tex] = texNode
- return nodesDictionary
-
-
-def getTexNodeDic(texture):
- return nodesDictionary.get(texture)
-
-
-def clearNodes(TreeNodes):
- TreeNodes.nodes.clear()
-
-
-def clearCycleMaterial(cmat):
- TreeNodes = cmat.node_tree
- clearNodes(TreeNodes)
-
-
-def copyMapping(textureSlot, textureMapping):
- textureMapping.scale.x = textureSlot.scale.x
- textureMapping.scale.y = textureSlot.scale.y
- textureMapping.scale.z = textureSlot.scale.z
-
-
-def addRGBMixNode(TreeNodes, textureSlot, mixRgbNode, prevTexNode, newTexNode, nodeType, textureIdx):
- try:
- links = TreeNodes.links
- mixRgbNode.name = '{} Mix {:d}'.format(nodeType, textureIdx)
- mixRgbNode.blend_type = textureSlot.blend_type
- mixRgbNode.inputs['Fac'].default_value = textureSlot.diffuse_color_factor
- links.new(prevTexNode.outputs['Color'], mixRgbNode.inputs['Color2'])
- links.new(newTexNode.outputs['Color'], mixRgbNode.inputs['Color1'])
- except:
- collect_report("ERROR: Failure to find link with a Mix node")
-
-
-def makeBiNodes(cmat):
- # Create Blender Internal Material Nodes
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
-
- BIFrame = TreeNodes.nodes.new(NODE_FRAME)
- BIFrame.name = 'BI Frame'
- BIFrame.label = 'BI Material'
-
- biShaderNodeMaterial = TreeNodes.nodes.new(BI_MATERIAL_NODE)
- biShaderNodeMaterial.parent = BIFrame
- biShaderNodeMaterial.name = 'BI Material'
- biShaderNodeMaterial.material = cmat
- biShaderNodeMaterial.location = 0, 600
-
- biShaderNodeOutput = TreeNodes.nodes.new(BI_OUTPUT_NODE)
- biShaderNodeOutput.parent = BIFrame
- biShaderNodeOutput.name = 'BI Output'
- biShaderNodeOutput.location = 200, 600
- try:
- links.new(biShaderNodeMaterial.outputs['Color'], biShaderNodeOutput.inputs['Color'])
- links.new(biShaderNodeMaterial.outputs['Alpha'], biShaderNodeOutput.inputs['Alpha'])
- except:
- collect_report("ERROR: Failure to find links with the BI Shader Material")
-
-
-def placeNode(node, posX, posY, deltaX, deltaY, countX, countY):
- nodeX = posX - (deltaX * countX)
- nodeY = posY - (deltaY * countY)
- node.location = nodeX, nodeY
-
-
-def makeImageTextureNode(TreeNodes, img):
- texNode = TreeNodes.nodes.new(TEXTURE_IMAGE_NODE)
- texNode.image = img
- return texNode
-
-
-def makeNodeUsingImage1(cmat, texture):
- TreeNodes = cmat.node_tree
- img = texture.image
- texNode = makeImageTextureNode(TreeNodes, img)
- return texNode
-
-
-def makeMainShader(TreeNodes):
- mainShader = TreeNodes.nodes.new(BSDF_DIFFUSE_NODE)
- mainShader.name = 'Diffuse BSDF'
- mainShader.location = 0, 0
- return mainShader
-
-
-def makeEmissionShader(TreeNodes):
- mainShader = TreeNodes.nodes.new(BSDF_EMISSION_NODE)
- mainShader.name = 'Emmission'
- mainShader.location = 0, 0
- return mainShader
-
-
-def makeMaterialOutput(TreeNodes):
- shout = TreeNodes.nodes.new(OUTPUT_NODE)
- shout.location = 200, 0
- return shout
-
-
-def replaceNode(oldNode, newNode):
- newNode.location = oldNode.location
- try:
- for link in oldNode.outputs['BSDF'].links:
- link.new(newNode.outputs['BSDF'], link.to_socket)
- for link in oldNode.inputs['Color'].links:
- link.new(newNode.inputs['Color'], link.from_socket)
- for link in oldNode.inputs['Normal'].links:
- link.new(newNode.inputs['Normal'], link.from_socket)
- except:
- collect_report("ERROR: Failure to replace node")
-
-
-def BIToCycleTexCoord(links, textureSlot, texCoordNode, textureMappingNode):
- # Texture Coordinates
- linkOutput = None
- if textureSlot.texture_coords in {'TANGENT', 'STRESS', 'STRAND'}:
- linkOutput = None
- elif textureSlot.texture_coords == 'REFLECTION':
- linkOutput = 'Reflection'
- elif textureSlot.texture_coords == 'NORMAL':
- linkOutput = 'Normal'
- elif textureSlot.texture_coords == 'WINDOW':
- linkOutput = 'Window'
- elif textureSlot.texture_coords == 'UV':
- linkOutput = 'UV'
- elif textureSlot.texture_coords == 'ORCO':
- linkOutput = 'Generated'
- elif textureSlot.texture_coords == 'OBJECT':
- linkOutput = 'Object'
- elif textureSlot.texture_coords == 'GLOBAL':
- linkOutput = 'Camera'
-
- if linkOutput:
- links.new(texCoordNode.outputs[linkOutput], textureMappingNode.inputs['Vector'])
-
-
-def createDiffuseNodes(cmat, texCoordNode, mainShader, materialOutput):
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
- texCount = len([node for node in TreeNodes.nodes if node.type == 'MAPPING'])
- currPosY = -textureNodeSizeY * texCount
-
- textureSlots = [textureSlot for textureSlot in cmat.texture_slots if
- (textureSlot and textureSlot.use_map_color_diffuse)]
-
- texCount = len(textureSlots)
- texNode = None
- latestNode = None
- groupName = 'Diffuse'
-
- if any(textureSlots):
- diffuseFrame = TreeNodes.nodes.new(NODE_FRAME)
- diffuseFrame.name = '{} Frame'.format(groupName)
- diffuseFrame.label = '{}'.format(groupName)
-
- for textureIdx, textureSlot in enumerate(textureSlots):
- texNode = getTexNodeDic(textureSlot.texture)
- if texNode:
- tex_node_name = getattr(texNode.image, "name", "")
- collect_report("INFO: Generating {} Nodes for: ".format(groupName) + tex_node_name)
- texNode.parent = diffuseFrame
- placeNode(texNode, -500 - ((texCount - 1) * 200),
- currPosY, textureNodeSizeX, textureNodeSizeY, 0, textureIdx)
-
- # Add mapping node
- textureMapping = TreeNodes.nodes.new(MAPPING_NODE)
- textureMapping.parent = diffuseFrame
- renameNode(textureMapping, '{} Mapping'.format(groupName), texCount, textureIdx)
- textureMapping.location = texNode.location + Vector((-400, 0))
- copyMapping(textureSlot, textureMapping)
-
- # Texture Coordinates
- BIToCycleTexCoord(links, textureSlot, texCoordNode, textureMapping)
-
- # Place the texture node
- renameNode(texNode, '{} Texture'.format(groupName), texCount, textureIdx)
- links.new(textureMapping.outputs['Vector'], texNode.inputs['Vector'])
-
- # Add multiply node
- colorMult = TreeNodes.nodes.new(RGB_MIX_NODE)
- colorMult.parent = diffuseFrame
- renameNode(colorMult, 'Color Mult', texCount, textureIdx)
- colorMult.blend_type = 'MIX'
- colorMult.inputs['Fac'].default_value = 1
- colorMult.inputs['Color1'].default_value = (1, 1, 1, 1)
-
- colorMult.location = texNode.location + Vector((200, 0))
- links.new(texNode.outputs['Color'], colorMult.inputs['Color2'])
-
- texNode = colorMult
- if textureSlot.use and textureIdx == 0:
- latestNode = texNode
-
- if textureSlot.use and textureIdx > 0:
- try:
- # Create a node to mix multiple texture nodes
- mixRgbNode = TreeNodes.nodes.new(RGB_MIX_NODE)
- mixRgbNode.parent = diffuseFrame
- addRGBMixNode(TreeNodes, textureSlot, mixRgbNode, texNode, latestNode,
- '{}'.format(groupName), textureIdx)
- mixRgbNode.location = Vector(
- (max(texNode.location.x, latestNode.location.x),
- (texNode.location.y + latestNode.location.y) / 2)) + Vector((200, 0)
- )
- latestNode = mixRgbNode
- except:
- continue
-
- if latestNode:
- links.new(latestNode.outputs['Color'], mainShader.inputs['Color'])
-
- # Y Position next texture node
- currPosY = currPosY - (textureNodeSizeY * (texCount))
-
- # BI Material to Cycles - Alpha Transparency
- textureSlots = [textureSlot for textureSlot in cmat.texture_slots if
- (textureSlot and textureSlot.use_map_alpha)]
- texCount = len(textureSlots)
- texNode = None
- latestNode = None
- for textureIdx, textureSlot in enumerate(textureSlots):
- texNode = getTexNodeDic(textureSlot.texture)
- if texNode:
- tex_node_name = getattr(texNode.image, "name", "")
- collect_report("INFO: Generating Transparency Nodes for: " + tex_node_name)
- if textureSlot.use and textureIdx == 0:
- latestNode = texNode
-
- if textureSlot.use and textureIdx > 0:
- try:
- # Create a node to mix multiple texture nodes
- mixAlphaNode = TreeNodes.nodes.new(RGB_MIX_NODE)
- mixAlphaNode.name = 'Alpha Mix {:d}'.format(textureIdx)
- mixAlphaNode.blend_type = textureSlot.blend_type
- mixAlphaNode.inputs['Fac'].default_value = textureSlot.diffuse_color_factor
- placeNode(mixAlphaNode, -200 - ((texCount - textureIdx - 1) * 200), 400 - 240,
- textureNodeSizeX, textureNodeSizeY, 0, 0)
- links.new(texNode.outputs['Alpha'], mixAlphaNode.inputs['Color2'])
- links.new(latestNode.outputs['Alpha'], mixAlphaNode.inputs['Color1'])
- latestNode = mixAlphaNode
- except:
- continue
- if latestNode:
- alphaMixShader = TreeNodes.nodes.get('Alpha Mix Shader')
- if alphaMixShader:
- if latestNode.type == 'TEX_IMAGE':
- outputLink = 'Alpha'
- else:
- outputLink = 'Color'
- links.new(latestNode.outputs[outputLink], alphaMixShader.inputs['Fac'])
-
-
-def createNormalNodes(cmat, texCoordNode, mainShader, materialOutput):
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
- texCount = len([node for node in TreeNodes.nodes if node.type == 'MAPPING'])
- currPosY = -textureNodeSizeY * texCount
-
- textureSlots = [textureSlot for textureSlot in cmat.texture_slots if
- (textureSlot and textureSlot.use_map_normal)]
- texCount = len(textureSlots)
- texNode = None
- latestNode = None
- groupName = 'Normal'
- if any(textureSlots):
- normalFrame = TreeNodes.nodes.new(NODE_FRAME)
- normalFrame.name = '{} Frame'.format(groupName)
- normalFrame.label = '{}'.format(groupName)
-
- for textureIdx, textureSlot in enumerate(textureSlots):
- texNode = getTexNodeDic(textureSlot.texture)
- if texNode:
- tex_node_name = getattr(texNode.image, "name", "")
- collect_report("INFO: Generating Normal Nodes for: " + tex_node_name)
- texNode.parent = normalFrame
- placeNode(texNode, -500 - ((texCount) * 200), currPosY,
- textureNodeSizeX, textureNodeSizeY, 0, textureIdx)
-
- # Add mapping node
- normalMapping = TreeNodes.nodes.new(MAPPING_NODE)
- normalMapping.parent = normalFrame
- renameNode(normalMapping, '{} Mapping'.format(groupName), texCount, textureIdx)
- normalMapping.location = texNode.location + Vector((-400, 0))
- copyMapping(textureSlot, normalMapping)
-
- # Texture Coordinates
- BIToCycleTexCoord(links, textureSlot, texCoordNode, normalMapping)
-
- # Place the texture node
- renameNode(texNode, '{} Texture'.format(groupName), texCount, textureIdx)
- if texNode.image.image:
- texNode.image.colorspace_settings.is_data = True
- links.new(normalMapping.outputs['Vector'], texNode.inputs['Vector'])
-
- # Add multiply node
- normalMult = TreeNodes.nodes.new(RGB_MIX_NODE)
- normalMult.parent = normalFrame
- renameNode(normalMult, 'Normal Mult', texCount, textureIdx)
- normalMult.blend_type = 'MIX'
- normalMult.inputs['Fac'].default_value = 1
- normalMult.inputs['Color1'].default_value = (.5, .5, 1, 1)
-
- normalMult.location = texNode.location + Vector((200, 0))
- links.new(texNode.outputs['Color'], normalMult.inputs['Color2'])
-
- texNode = normalMult
- if textureSlot.use and textureIdx == 0:
- latestNode = texNode
-
- if textureSlot.use and textureIdx > 0:
- try:
- # Create a node to mix multiple texture nodes
- mixRgbNode = TreeNodes.nodes.new(RGB_MIX_NODE)
- mixRgbNode.parent = normalFrame
- addRGBMixNode(TreeNodes, textureSlot, mixRgbNode, texNode, latestNode,
- '{}'.format(groupName), textureIdx)
- mixRgbNode.location = Vector(
- (max(texNode.location.x, latestNode.location.x),
- (texNode.location.y + latestNode.location.y) / 2)) + Vector((200, 0)
- )
- latestNode = mixRgbNode
- except:
- continue
-
- if latestNode:
- normalMapNode = TreeNodes.nodes.new(NORMAL_MAP_NODE)
- normalMapNode.parent = normalFrame
- normalMapNode.location = latestNode.location + Vector((200, 0))
- links.new(latestNode.outputs['Color'], normalMapNode.inputs['Color'])
- links.new(normalMapNode.outputs['Normal'], mainShader.inputs['Normal'])
-
-
-def createSpecularNodes(cmat, texCoordNode, mainShader, mainDiffuse, materialOutput):
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
- texCount = len([node for node in TreeNodes.nodes if node.type == 'MAPPING'])
- currPosY = -textureNodeSizeY * texCount
-
- textureSlots = [textureSlot for textureSlot in cmat.texture_slots if
- (textureSlot and textureSlot.use_map_color_spec)]
- texCount = len(textureSlots)
- texNode = None
- latestNode = None
- groupName = 'Specular'
- if any(textureSlots):
- specularFrame = TreeNodes.nodes.new(NODE_FRAME)
- specularFrame.name = '{} Frame'.format(groupName)
- specularFrame.label = '{}'.format(groupName)
-
- for textureIdx, textureSlot in enumerate(textureSlots):
- texNode = getTexNodeDic(textureSlot.texture)
- if texNode:
- tex_node_name = getattr(texNode.image, "name", "")
- collect_report("INFO: Generating {} Nodes for: ".format(groupName) + tex_node_name)
- texNode.parent = specularFrame
- placeNode(texNode, -500 - ((texCount) * 200),
- currPosY, textureNodeSizeX, textureNodeSizeY, 0, textureIdx)
-
- # Add mapping node
- specularMapping = TreeNodes.nodes.new(MAPPING_NODE)
- specularMapping.parent = specularFrame
- renameNode(specularMapping, '{} Mapping'.format(groupName), texCount, textureIdx)
- specularMapping.location = texNode.location + Vector((-400, 0))
- copyMapping(textureSlot, specularMapping)
-
- # Texture Coordinates
- BIToCycleTexCoord(links, textureSlot, texCoordNode, specularMapping)
-
- # Place the texture node
- renameNode(texNode, '{} Texture'.format(groupName), texCount, textureIdx)
- links.new(specularMapping.outputs['Vector'], texNode.inputs['Vector'])
-
- # Add multiply node
- specularMult = TreeNodes.nodes.new(RGB_MIX_NODE)
- specularMult.parent = specularFrame
- renameNode(specularMult, 'Specular Mult', texCount, textureIdx)
- specularMult.blend_type = 'MULTIPLY'
- specularMult.inputs['Fac'].default_value = 1
- specularMult.inputs['Color1'].default_value = (1, 1, 1, 1)
-
- specularMult.location = texNode.location + Vector((200, 0))
- links.new(texNode.outputs['Color'], specularMult.inputs['Color2'])
-
- texNode = specularMult
- if textureSlot.use and textureIdx == 0:
- latestNode = texNode
-
- if textureSlot.use and textureIdx > 0:
- try:
- # Create a node to mix multiple texture nodes
- mixRgbNode = TreeNodes.nodes.new(RGB_MIX_NODE)
- mixRgbNode.parent = specularFrame
- addRGBMixNode(TreeNodes, textureSlot, mixRgbNode, texNode, latestNode,
- '{}'.format(groupName), textureIdx)
- mixRgbNode.location = Vector(
- (max(texNode.location.x, latestNode.location.x),
- (texNode.location.y + latestNode.location.y) / 2)) + Vector((200, 0)
- )
- latestNode = mixRgbNode
- except:
- continue
-
- if latestNode:
- try:
- glossShader = TreeNodes.nodes.new(BSDF_GLOSSY_NODE)
- RGBToBW = TreeNodes.nodes.new(RGB_TO_BW_NODE)
- RGBToBW.location = Vector((0, latestNode.location.y)) + Vector((0, 0))
- glossShader.location = Vector((0, latestNode.location.y)) + Vector((0, -80))
-
- links.new(latestNode.outputs['Color'], glossShader.inputs['Color'])
- links.new(latestNode.outputs['Color'], RGBToBW.inputs['Color'])
-
- outputNode = TreeNodes.nodes.get('Material Output')
- spec_mixer_1 = TreeNodes.nodes.new(SHADER_MIX_NODE)
- spec_mixer_1.location = outputNode.location
- spec_mixer_2 = TreeNodes.nodes.new(SHADER_MIX_NODE)
- spec_mixer_2.inputs['Fac'].default_value = .4
- spec_mixer_2.location = outputNode.location + Vector((180, 0))
- links.new(spec_mixer_1.outputs['Shader'], spec_mixer_2.inputs[2])
- links.new(spec_mixer_2.outputs['Shader'], outputNode.inputs['Surface'])
- links.new(RGBToBW.outputs['Val'], spec_mixer_1.inputs['Fac'])
-
- links.new(glossShader.outputs['BSDF'], spec_mixer_1.inputs[2])
-
- outputNode.location += Vector((360, 0))
- normalMapNode = TreeNodes.nodes.get('Normal Map')
- links.new(normalMapNode.outputs['Normal'], glossShader.inputs['Normal'])
-
- if mainDiffuse.type == 'BSDF_DIFFUSE':
- outputLink = 'BSDF'
- else:
- outputLink = 'Shader'
-
- links.new(mainDiffuse.outputs[outputLink], spec_mixer_1.inputs[1])
- links.new(mainDiffuse.outputs[outputLink], spec_mixer_2.inputs[1])
- except:
- return
-
-
-def createEmissionNodes(cmat, texCoordNode, mainShader, materialOutput):
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
- texCount = len([node for node in TreeNodes.nodes if node.type == 'MAPPING'])
- currPosY = -textureNodeSizeY * texCount
-
- textureSlots = [textureSlot for textureSlot in cmat.texture_slots if
- (textureSlot and textureSlot.use_map_emit)]
- texCount = len(textureSlots)
- texNode = None
- latestNode = None
- groupName = 'Emission'
- if any(textureSlots):
- emissionFrame = TreeNodes.nodes.new(NODE_FRAME)
- emissionFrame.name = '{} Frame'.format(groupName)
- emissionFrame.label = '{}'.format(groupName)
-
- for textureIdx, textureSlot in enumerate(textureSlots):
- texNode = getTexNodeDic(textureSlot.texture)
- if texNode:
- tex_node_name = getattr(texNode.image, "name", "")
- collect_report("INFO: Generating {} Nodes for: ".format(groupName) + tex_node_name)
- texNode.parent = emissionFrame
- placeNode(texNode, -500 - ((texCount) * 200), currPosY,
- textureNodeSizeX, textureNodeSizeY, 0, textureIdx)
-
- # Add mapping node
- emissionMapping = TreeNodes.nodes.new(MAPPING_NODE)
- emissionMapping.parent = emissionFrame
- renameNode(emissionMapping, '{} Mapping'.format(groupName), texCount, textureIdx)
- emissionMapping.location = texNode.location + Vector((-400, 0))
- copyMapping(textureSlot, emissionMapping)
-
- # Texture Coordinates
- BIToCycleTexCoord(links, textureSlot, texCoordNode, emissionMapping)
-
- # Place the texture node
- renameNode(texNode, '{} Texture'.format(groupName), texCount, textureIdx)
- if texNode.image.image:
- texNode.image.colorspace_settings.is_data = True
- links.new(emissionMapping.outputs['Vector'], texNode.inputs['Vector'])
-
- # Add multiply node
- emissionMult = TreeNodes.nodes.new(RGB_MIX_NODE)
- emissionMult.parent = emissionFrame
- renameNode(emissionMult, 'Emission Mult', texCount, textureIdx)
- emissionMult.blend_type = 'MIX'
- emissionMult.inputs['Fac'].default_value = 1
- emissionMult.inputs['Color1'].default_value = (0, 0, 0, 1)
-
- emissionMult.location = texNode.location + Vector((200, 0))
- links.new(texNode.outputs['Color'], emissionMult.inputs['Color2'])
-
- texNode = emissionMult
- if textureSlot.use and textureIdx == 0:
- latestNode = texNode
-
- if textureSlot.use and textureIdx > 0:
- try:
- # Create a node to mix multiple texture nodes
- mixRgbNode = TreeNodes.nodes.new(RGB_MIX_NODE)
- mixRgbNode.parent = emissionFrame
- addRGBMixNode(TreeNodes, textureSlot, mixRgbNode, texNode, latestNode,
- '{}'.format(groupName), textureIdx)
- mixRgbNode.location = Vector(
- (max(texNode.location.x, latestNode.location.x),
- (texNode.location.y + latestNode.location.y) / 2)) + Vector((200, 0)
- )
- latestNode = mixRgbNode
- except:
- continue
-
- if latestNode:
- try:
- emissionNode = TreeNodes.nodes.new(BSDF_EMISSION_NODE)
- emissionNode.inputs['Strength'].default_value = 1
- addShaderNode = TreeNodes.nodes.new(SHADER_ADD_NODE)
- addShaderNode.location = materialOutput.location + Vector((0, -100))
- xPos = mainShader.location.x
- yPos = latestNode.location.y
-
- emissionNode.location = Vector((xPos, yPos))
- materialOutput.location += Vector((400, 0))
-
- node = materialOutput.inputs[0].links[0].from_node
- node.location += Vector((400, 0))
-
- links.new(latestNode.outputs['Color'], emissionNode.inputs['Color'])
- links.new(emissionNode.outputs['Emission'], addShaderNode.inputs[1])
- links.new(mainShader.outputs['BSDF'], addShaderNode.inputs[0])
- links.new(addShaderNode.outputs['Shader'], node.inputs[2])
- except:
- return
-
-
-def renameNode(node, baseName, nodesCount, nodeIndex):
- if nodesCount == 1:
- node.name = baseName
- else:
- node.name = '{} {:d}'.format(baseName, nodeIndex + 1)
-
-
-def hasAlphaTex(cmat):
- tex_is_transp = False
- for textureSlot in cmat.texture_slots:
- if textureSlot:
- if textureSlot.use:
- if textureSlot.use_map_alpha:
- tex_is_transp = tex_is_transp or True
- return tex_is_transp
-
-
-def AutoNode(active=False, operator=None):
- collect_report("________________________________________", True, False)
- collect_report("START CYCLES CONVERSION")
-
- if active:
- materials = [mat for obj in bpy.context.selected_objects if
- obj.type == 'MESH' for mat in obj.data.materials]
- else:
- materials = bpy.data.materials
-
- # No Materials for the chosen action - abort
- if not materials:
- if operator:
- if active:
- warning_messages(operator, 'CONV_NO_SEL_MAT', override=True)
- else:
- warning_messages(operator, 'CONV_NO_SC_MAT', override=True)
- return
-
- for cmat in materials:
- # check for empty material (it will fall through the first check)
- test_empty = getattr(cmat, "name", None)
- if test_empty is None:
- collect_report("INFO: An empty material was hit, skipping")
- continue
- else:
- cmat.use_nodes = True
- clearCycleMaterial(cmat)
- makeBiNodes(cmat)
- makeCyclesFromBI(cmat)
-
- collect_report("Conversion finished !", False, True)
-
- bpy.context.scene.render.engine = 'CYCLES'
-
-
-def makeCyclesFromBI(cmat):
- mat_name = getattr(cmat, "name", "NO NAME")
- collect_report("Converting Material: " + mat_name)
-
- global nodesDictionary
- TreeNodes = cmat.node_tree
- links = TreeNodes.links
-
- # Convert this material from non-nodes to Cycles nodes
- mainShader = None
- mainDiffuse = None
- Mix_Alpha = None
-
- tex_is_transp = hasAlphaTex(cmat)
-
- cmat_use_transp = cmat.use_transparency and cmat.alpha < 1
- cmat_trans_method = cmat.transparency_method
- cmat_ior = cmat.raytrace_transparency.ior
- cmat_transp_z = cmat_use_transp and cmat_trans_method == 'Z_TRANSPARENCY'
- cmat_transp_ray = cmat_use_transp and cmat_trans_method == 'RAYTRACE' and cmat_ior == 1
- cmat_mirror = cmat.raytrace_mirror.use
- cmat_mirror_fac = cmat.raytrace_mirror.reflect_factor
-
- # Material Shaders
- # Diffuse nodes
- # --------------------------------------
-
- # Make Diffuse and Output nodes
- mainShader = makeMainShader(TreeNodes)
- mainShader.inputs['Roughness'].default_value = math.sqrt(max(cmat.specular_intensity, 0.0))
- mainDiffuse = mainShader
- materialOutput = makeMaterialOutput(TreeNodes)
- links.new(mainShader.outputs['BSDF'], materialOutput.inputs['Surface'])
-
- texCoordNode = TreeNodes.nodes.new(COORD_NODE)
- texCoordNode.name = 'Texture Coordinate'
-
- # Material Transparent
- if not cmat_mirror and cmat_use_transp and tex_is_transp and (cmat_transp_z or cmat_transp_ray):
- collect_report("INFO: Make TRANSPARENT material nodes: " + cmat.name)
- Mix_Alpha = TreeNodes.nodes.new(SHADER_MIX_NODE)
- Mix_Alpha.name = 'Alpha Mix Shader'
- Mix_Alpha.location = materialOutput.location
- materialOutput.location += Vector((180, 0))
- Mix_Alpha.inputs['Fac'].default_value = cmat.alpha
- transparentShader = TreeNodes.nodes.new(BSDF_TRANSPARENT_NODE)
- transparentShader.location = mainShader.location
- mainShader.location += Vector((0, -100))
- links.new(transparentShader.outputs['BSDF'], Mix_Alpha.inputs[1])
- links.new(mainShader.outputs['BSDF'], Mix_Alpha.inputs[2])
- links.new(Mix_Alpha.outputs['Shader'], materialOutput.inputs['Surface'])
- mainDiffuse = Mix_Alpha
-
- if cmat_mirror and cmat_mirror_fac > 0.001:
- if cmat_use_transp:
- # Material Glass
- collect_report("INFO: Make GLASS shader node: " + cmat.name)
- newShader = TreeNodes.nodes.new(BSDF_GLASS_NODE)
- shader = newShader
- replaceNode(shader, newShader)
- TreeNodes.nodes.remove(shader)
- else:
- # Material Mirror
- collect_report("INFO: Make MIRROR shader node: " + cmat.name)
- newShader = TreeNodes.nodes.new(BSDF_GLOSSY_NODE)
- shader = newShader
- replaceNode(shader, newShader)
- TreeNodes.nodes.remove(shader)
-
- nodesDictionary = makeTextureNodeDict(cmat)
-
- # --------------------------------------
- # Texture nodes
-
- # BI Material to Cycles - Diffuse Textures
- createDiffuseNodes(cmat, texCoordNode, mainShader, materialOutput)
-
- # BI Material to Cycles - Normal map
- createNormalNodes(cmat, texCoordNode, mainShader, materialOutput)
-
- # BI Material to Cycles - Specular map
- createSpecularNodes(cmat, texCoordNode, mainShader, mainDiffuse, materialOutput)
-
- # BI Material to Cycles - Emission map
- createEmissionNodes(cmat, texCoordNode, mainShader, materialOutput)
-
- # Texture coordinates
- # list all nodes connected to outputs
- mappingNodes = [link.to_node for output in texCoordNode.outputs for link in output.links]
- mappingNodesCount = len(mappingNodes)
-
- if mappingNodes:
- xList = [node.location.x for node in mappingNodes]
- yList = [node.location.y for node in mappingNodes]
- minPosX = min(xList) - 400
- avgPosY = sum(yList) / mappingNodesCount
- texCoordNode.location = Vector((minPosX, avgPosY))
-
-
-# -----------------------------------------------------------------------------
-# Operator Classes
-
-class material_convert_all(Operator):
- bl_idname = "xps_tools.convert_to_cycles_all"
- bl_label = "Convert All Materials"
- bl_description = ("Convert All Materials to BI and Cycles Nodes\n"
- "Needs saving the .blend file first")
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(cls, context):
- return (bpy.data.filepath != "" and c_is_cycles_addon_enabled() and
- c_data_has_materials())
-
- def execute(self, context):
- AutoNode(False, self)
-
- return {'FINISHED'}
-
-
-class material_convert_selected(Operator):
- bl_idname = "xps_tools.convert_to_cycles_selected"
- bl_label = "Convert All Materials From Selected Objects"
- bl_description = ("Convert All Materials on Selected Objects to BI and Cycles Nodes\n"
- "Needs saving the .blend file first")
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(cls, context):
- return (bpy.data.filepath != "" and c_data_has_materials() and
- c_is_cycles_addon_enabled() and
- bool(next((obj for obj in context.selected_objects if obj.type == 'MESH'), None))
- )
-
- def execute(self, context):
- AutoNode(True, self)
-
- return {'FINISHED'}
-
-
-def register():
- bpy.utils.register_module(__name__)
- pass
-
-
-def unregister():
- bpy.utils.unregister_module(__name__)
- pass
-
-
-if __name__ == "__main__":
- register()