def execute(self, context): if not context.node: Debug.PrintError("No active node!") return {'CANCELLED'} if context.node.bl_idname != "VRayNodeMtlVRmat": Debug.PrintError("Selected node is not of type VRayNodeMtlVRmat!") return {'CANCELLED'} MtlVRmat = context.node.MtlVRmat if not MtlVRmat.filename: Debug.PrintError("Filepath is not set!") return {'CANCELLED'} filePath = os.path.normpath(bpy.path.abspath(MtlVRmat.filename)) if not os.path.exists(filePath): Debug.PrintError("File doesn't exist!") return {'CANCELLED'} if filePath.endswith(".vrscene"): VRAY_MT_MaterialName.ma_list = GetMaterialsNames(filePath) else: VRAY_MT_MaterialName.ma_list = GetXMLMaterialsNames(filePath) bpy.ops.wm.call_menu(name=VRAY_MT_MaterialName.bl_idname) return {'FINISHED'}
def writeDatablock(bus, pluginModule, pluginName, propGroup, overrideParams): scene = bus['scene'] o = bus['output'] if not propGroup.use: return if not propGroup.bake_node: Debug("Bake object is not set!", msgType='ERROR') return bakeObject = BlenderUtils.GetSceneObject(scene, propGroup.bake_node) if not bakeObject: Debug("Bake object \"%s\" not found!" % propGroup.bake_node, msgType='ERROR') return o.set('SETTINGS', 'UVWGenChannel', 'UVWbakeView') o.writeHeader() o.writeAttibute('uvw_channel', propGroup.uv_channel) o.writeAttibute('uvw_transform', mathutils.Matrix.Identity(4)) o.writeFooter() overrideParams.update({ 'bake_node': BlenderUtils.GetObjectName(bakeObject), 'bake_uvwgen': "UVWbakeView", }) return ExportUtils.WritePluginCustom(bus, pluginModule, pluginName, propGroup, overrideParams)
def GenerateJsonDescription(pluginModule): import json if not hasattr(pluginModule, 'PluginParams'): Debug("Plugin '%s' has 'PluginParams'!" % p, msgType='ERROR') return None pluginWidgetTmpl = """{ "widgets": []}""" if hasattr(pluginModule, 'PluginWidget'): pluginWidget = pluginModule.PluginWidget else: pluginWidget = pluginWidgetTmpl plugWdgDict = None try: plugWdgDict = json.loads(pluginWidget) except ValueError as e: print(p, e) jsonPlugin = { 'Type': pluginModule.TYPE, 'ID': pluginModule.ID, 'Name': pluginModule.NAME, 'Desciption': pluginModule.DESC, 'Parameters': pluginModule.PluginParams, 'Widget': plugWdgDict, } return jsonPlugin
def LoadPlugins(PluginDict, PluginIDDict): pluginsDir = GetPluginsDir() if not pluginsDir or not os.path.exists(pluginsDir): Debug("Plugin directory not found!", msgType='ERROR') return plugins = [] for dirName, subdirList, fileList in os.walk(pluginsDir): if dirName.endswith("__pycache__"): continue if not dirName in sys.path: PLUGINS_DIRS.append(dirName) sys.path.append(dirName) for fname in fileList: if fname == "__init__.py": continue if not fname.endswith(".py"): continue module_name, module_ext = os.path.splitext(fname) plugins.append(__import__(module_name)) for plugin in plugins: if not hasattr(plugin, 'ID'): continue PluginDict[plugin.TYPE][plugin.ID] = plugin PluginIDDict[plugin.ID] = plugin
def writeFooter(self): if not self.fileManager: Debug("File manager is not set!", msgType='ERROR') return # Could also mean that plugin is already exported # if not self.pluginID and not self.pluginName: return # No attributes are collected for write if not self.pluginAttrs and self.pluginID not in NoAttrPlugins: return p = "\n%s %s {" % (self.pluginID, self.pluginName) for attrName in sorted(self.pluginAttrs.keys()): p += "\n\t%s=%s;" % (attrName, self.pluginAttrs[attrName]) p += "\n}\n" outputFile = self.fileManager.getOutputFile(self.pluginType) if self.pluginID == 'VRayStereoscopicSettings': outputFile = self.fileManager.getOutputFile('CAMERA') outputFile.write(p) # Reset current plugin self.pluginType = None self.pluginID = None self.pluginName = None self.pluginAttrs = None
def closeFiles(self): Debug("VRayExportFiles::closeFiles()") if not self.files: return for fileType in self.files: f = self.files[fileType] if f and not f.closed: f.close()
def AddOutput(node, socketType, socketName, attrName=None): if socketName in node.outputs: return Debug("Adding output socket: '%s' <= '%s'" % (socketName, attrName), msgType='INFO') node.outputs.new(socketType, socketName) createdSocket = node.outputs[socketName] if attrName is not None: createdSocket.vray_attr = attrName
def RegisterDynamicSocketClass(pluginName, socketTypeName, attrName): global DYNAMIC_SOCKET_CLASSES global DYNAMIC_SOCKET_CLASS_NAMES if not attrName: Debug("Could not register dynamic socket type for %s::%s" % (node.bl_idname, socketTypeName), msgType='ERROR') return if socketTypeName not in DYNAMIC_SOCKET_OVERRIDES: return typeName = GetDynamicSocketClass(pluginName, socketTypeName, attrName) if not hasattr(bpy.types, typeName): INFO_BASESES = 0 INFO_DYNAMIC_ATTR = 1 INFO_ATTRIBUTES = 2 typeInfo = copy.deepcopy(DYNAMIC_SOCKET_OVERRIDES[socketTypeName]) overrideName = typeInfo[INFO_DYNAMIC_ATTR][0] overrideType = typeInfo[INFO_DYNAMIC_ATTR][1] overrideParams = typeInfo[INFO_DYNAMIC_ATTR][2] pluginParam = FindPluginUIAttr(pluginName, attrName) if pluginParam: overrideParams['soft_min'] = pluginParam.get('soft_min', -100) overrideParams['soft_max'] = pluginParam.get('soft_max', 100) typeInfo[INFO_ATTRIBUTES][overrideName] = overrideType( **overrideParams) typeInfo[INFO_ATTRIBUTES]['bl_idname'] = typeName typeInfo[INFO_ATTRIBUTES][ 'vray_socket_base_type'] = bpy.props.StringProperty( name="V-Ray Attribute", description="V-Ray plugin socket attribute", options={'HIDDEN'}, default="") newType = type( typeName, typeInfo[INFO_BASESES], typeInfo[INFO_ATTRIBUTES], ) bpy.utils.register_class(newType) DYNAMIC_SOCKET_CLASSES.add(newType) DYNAMIC_SOCKET_CLASS_NAMES.add(typeName)
def UpdateJsonDescription(): pluginsDir = GetPluginsDir() if not pluginsDir or not os.path.exists(pluginsDir): Debug("Plugin directory not found!", msgType='ERROR') return jsonDirpath = os.path.expanduser("~/devel/vray/vray_json") for p in PLUGINS_ID: pluginModule = PLUGINS_ID[p] jsonFilepath = os.path.join(jsonDirpath, "%s.json" % p) with open(jsonFilepath, 'w') as f: jsonPlugin = GenerateJsonDescription(pluginID, outputFile) if jsonPlugin is not None: json.dump(jsonPlugin, f, indent=4, sort_keys=True)
def AddInput(node, socketType, socketName, attrName=None, default=None): if socketName in node.inputs: return Debug("Adding input socket: '%s' <= '%s'" % (socketName, attrName), msgType='INFO') node.inputs.new(socketType, socketName) createdSocket = node.inputs[socketName] if attrName is not None: createdSocket.vray_attr = attrName if default is not None: # Some socket intensionally have no 'value' if hasattr(createdSocket, 'value'): if socketType in {'VRaySocketColor', 'VRaySocketVector'}: createdSocket.value = (default[0], default[1], default[2]) else: createdSocket.value = default
def InitDynamicSocketTypes(): skip_plugins = { "GeomVRayPattern", "Node", "VRayExporter", "Includer", "CameraStereoscopic", "ExportSets", "VRayQuickSettings" } for pluginId in PluginUtils.PLUGINS_DESC: if pluginId in skip_plugins: continue pluginDesc = PluginUtils.PLUGINS_DESC[pluginId] if 'Parameters' not in pluginDesc: Debug("Plugin [%s] missing Parameters" % pluginId, msgType='ERROR') continue pluginParams = pluginDesc['Parameters'] for param in pluginParams: attrName = param.get('attr', None) paramType = param.get('type', None) paramSocketType = AttributeUtils.TypeToSocket.get( param.get('type', None), None) if not paramSocketType: continue RegisterDynamicSocketClass(pluginId, paramSocketType, attrName)
def printInfo(self): Debug('Export directory: "%s"' % self.exportDirectory) if self.assetSubdirs: Debug('Asset directories:') Debug(' Images: "%s"' % self.assetSubdirs['image']) Debug(' IES: "%s"' % self.assetSubdirs['ies']) Debug(' Proxy: "%s"' % self.assetSubdirs['proxy']) Debug(' Misc: "%s"' % self.assetSubdirs['misc']) Debug('Export filename: "%s"' % self.exportFilename) if self.filePrefix: Debug('Expicit prefix: "%s"' % self.filePrefix) Debug('Separate files: %s' % self.separateFiles) if self.imgFilename is not None: Debug('Output directory: "%s"' % self.imgDirectory) Debug('Output file: "%s"' % self.imgFilename) Debug('Load file: "%s"' % self.imgLoadFilename)
def write(self, pluginType, data): if not self.fileManager: Debug("File manager is not set!", msgType='ERROR') return self.fileManager.getFileByPluginType(pluginType).write(data)
def WritePluginParams(bus, pluginModule, pluginName, propGroup, mappedParams): scene = bus['scene'] o = bus['output'] VRayScene = scene.vray VRayDR = VRayScene.VRayDR if not hasattr(pluginModule, 'PluginParams'): Debug("Module %s doesn't have PluginParams!" % pluginModule.ID, msgType='ERROR') return for attrDesc in sorted(pluginModule.PluginParams, key=lambda t: t['attr']): attrName = attrDesc['attr'] skip = attrDesc.get('skip', False) if skip and attrDesc['attr'] not in mappedParams: continue # Skip output attributes if attrDesc['type'] in AttributeUtils.OutputTypes: continue # Type could be skipped, but mappedParams could contain a manually defined value for it if attrDesc['type'] in AttributeUtils.SkippedTypes and attrDesc[ 'attr'] not in mappedParams: continue # Skip attibutes that should be mapped, but are not mapped, # we will use parameter value then if attrDesc['type'] in AttributeUtils.InputTypes and attrDesc[ 'attr'] not in mappedParams: continue value = None if attrName in mappedParams: value = mappedParams[attrName] # This allows us to use None to skip # particular parameter export if value is None: continue if 'options' in attrDesc: if 'EXPORT_AS_IS' in attrDesc['options']: o.writeAttibute(attrName, value) continue if value is None: value = getattr(propGroup, attrName) if value is None: Debug("%s.%s value is None!" % (pluginName, attrName), msgType='ERROR') continue if attrDesc['type'] in AttributeUtils.PluginTypes and not value: continue if attrDesc['type'] in {'TRANSFORM', 'MATRIX', 'VECTOR'}: if not value: continue if attrDesc['type'] in {'STRING'}: if not value: continue subtype = attrDesc.get('subtype') if subtype in {'FILE_PATH', 'DIR_PATH'}: value = BlenderUtils.GetFullFilepath(value) if subtype == 'FILE_PATH': if VRayDR.on: if VRayDR.assetSharing == 'SHARE': value = PathUtils.CopyDRAsset(bus, value) elif subtype == 'DIR_PATH': # Ensure slash at the end of directory path value = os.path.normpath(value) + os.sep # NOTE: Additional check for some plugins with 'autosave' # options. Create directories only if 'autosave' is on needCreateDir = True if pluginName in { 'SettingsCaustics', 'SettingsIrradianceMap', 'SettingsLightCache' }: if not getattr(propGroup, 'auto_save'): needCreateDir = False if needCreateDir: value = PathUtils.CreateDirectoryFromFilepath(value) value = '"%s"' % value o.writeAttibute(attrName, value)
def done(self): if not self.fileManager: Debug("File manager is not set!", msgType='ERROR') else: self.fileManager.writeIncludes() self.fileManager.closeFiles()
def AddInput(node, socketType, socketName, attrName=None, default=None): if socketName in node.inputs: return baseType = socketType foundPlugin = None if attrName and socketType in DYNAMIC_SOCKET_OVERRIDES: # get possible plugins for this node test_plugins = [] if hasattr(node, 'vray_plugin'): test_plugins.append(node.vray_plugin) if hasattr(node, 'vray_plugins'): for plugin in node.vray_plugins: test_plugins.append(plugin) for attr in dir(node): if attr in PLUGINS_ID: test_plugins.append(attr) # test each plugin to find where this attribute comes from for plugin in test_plugins: dynamicType = GetDynamicSocketClass(plugin, socketType, attrName) if dynamicType in DYNAMIC_SOCKET_CLASS_NAMES: foundPlugin = plugin socketType = dynamicType break # fall-back to static socket type if len(test_plugins) == 0: Debug("Can't find vray_plugins for %s" % node.bl_idname, msgType='ERROR') foundPlugin = 'NONE' socketType = baseType if not foundPlugin: Debug("Can't find dynamic socket type for: %s::%s" % (node.bl_idname, socketName), msgType='ERROR') return # register the socket for this node node.inputs.new(socketType, socketName) createdSocket = node.inputs[socketName] if attrName is not None: if not hasattr(createdSocket, 'vray_attr'): Debug("vray_attr mising from socketType: %s::%s" % (node.bl_idname, socketName), msgType='ERROR') else: createdSocket.vray_attr = attrName if hasattr(createdSocket, 'vray_socket_base_type'): createdSocket.vray_socket_base_type = baseType if default is not None: # Some socket intensionally have no 'value' if hasattr(createdSocket, 'value'): # we are interested if the base type is not scalar if baseType in {'VRaySocketColor', 'VRaySocketVector'}: createdSocket.value = (default[0], default[1], default[2]) else: createdSocket.value = default
def execute(self, context): node = context.node if not node: Debug.PrintError("No active node!") return {'CANCELLED'} if node.bl_idname != "VRayNodeMtlVRmat": Debug.PrintError("Selected node is not of type VRayNodeMtlVRmat!") return {'CANCELLED'} MtlVRmat = node.MtlVRmat if not MtlVRmat.filename: Debug.PrintError("Filepath is not set!") return {'CANCELLED'} if not MtlVRmat.mtlname: Debug.PrintError("Material is not chosen!") return {'CANCELLED'} filePath = os.path.normpath(bpy.path.abspath(MtlVRmat.filename)) if not os.path.exists(filePath): Debug.PrintError("File doesn't exist!") return {'CANCELLED'} namePrefix = "" vrsceneDict = [] if filePath.endswith(".vrscene"): vrsceneDict = ParseVrscene(filePath) else: vrsceneDict = ParseVrmat(filePath) namePrefix = "/" # Preview data from the file # # for pluginDesc in vrsceneDict: # pluginID = pluginDesc['ID'] # pluginName = pluginDesc['Name'] # pluginAttrs = pluginDesc['Attributes'] # # print("Plugin:") # print(" Type: %s" % pluginID) # print(" Name: %s" % pluginName) # print(" Attributes:") # for attrName in pluginAttrs: # print(" %s = %s" % (attrName, pluginAttrs[attrName])) # Find requested material plugin # mtlName = namePrefix + MtlVRmat.mtlname mtlPlugDesc = NodesImport.getPluginByName(vrsceneDict, mtlName) if not mtlPlugDesc: print("Requested material is not found!") return {'CANCELLED'} ntree = context.space_data.edit_tree # Now lets start creating nodes # mtlNode = NodesImport.createNode(ntree, node, vrsceneDict, mtlPlugDesc) # Connect material output to our node # ntree.links.new(mtlNode.outputs['Material'], node.inputs['Material']) NodesTools.rearrangeTree(ntree, node) return {'FINISHED'}