diff options
author | Maurice Raybaud <mauriceraybaud@hotmail.fr> | 2017-01-29 23:28:41 +0300 |
---|---|---|
committer | Maurice Raybaud <mauriceraybaud@hotmail.fr> | 2017-01-29 23:28:41 +0300 |
commit | 6f40579d5bd29e235b8aa372297de5eabf23aab7 (patch) | |
tree | af9e95de45d0feb630600712e111ef8e2a9351fc /render_povray/nodes.py | |
parent | bafb8d353d64aa62be4dfeb1892aab4e2625053d (diff) |
Added Basic Nodes support by Lanuhum
Diffstat (limited to 'render_povray/nodes.py')
-rw-r--r-- | render_povray/nodes.py | 1299 |
1 files changed, 1299 insertions, 0 deletions
diff --git a/render_povray/nodes.py b/render_povray/nodes.py new file mode 100644 index 00000000..41b0caf1 --- /dev/null +++ b/render_povray/nodes.py @@ -0,0 +1,1299 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +import bpy + +from bpy.types import Node, ShaderNodeTree, CompositorNodeTree, TextureNodeTree#, NodeSocket + + +from bpy.props import ( + StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty, + #PointerProperty, + #CollectionProperty, + ) + + + +############### object + +class ObjectNodeTree(bpy.types.NodeTree): + '''Povray Material Nodes''' + + bl_idname = 'ObjectNodeTree' + bl_label = 'Povray Object Nodes' + bl_icon = 'PLUGIN' + + @classmethod + def poll(cls, context): + return context.scene.render.engine == 'POVRAY_RENDER' + + @classmethod + def get_from_context(cls, context): + ob = context.active_object + if ob and ob.type not in {'LAMP'}: + ma = ob.active_material + if ma != None: + nt_name = ma.node_tree + if nt_name != '': + return nt_name, ma, ma + return (None, None, None) + + def update(self): + self.refresh = True +################### output ############################################################################################# + +class PovrayOutputNode(Node, ObjectNodeTree): + '''Output''' + bl_idname = 'PovrayOutputNode' + bl_label = 'Output' + bl_icon = 'SOUND' + + def init(self, context): + + self.inputs.new('PovraySocketTexture', "Texture") + + def draw_buttons(self, context, layout): + + ob=context.object + layout.prop(ob.pov, "object_ior",slider=True) + + def draw_buttons_ext(self, context, layout): + + ob=context.object + layout.prop(ob.pov, "object_ior",slider=True) + + def draw_label(self): + return "Output" + + + +################### material ########################################################################################### +class PovrayTextureNode(Node, ObjectNodeTree): + '''Texture''' + bl_idname = 'PovrayTextureNode' + bl_label = 'Simple texture' + bl_icon = 'SOUND' + + def init(self, context): + + color=self.inputs.new('PovraySocketColor', "Pigment") + color.default_value=(1,1,1) + normal=self.inputs.new('NodeSocketFloat', "Normal") + normal.hide_value=True + finish=self.inputs.new('NodeSocketVector', "Finish") + finish.hide_value=True + + self.outputs.new('PovraySocketTexture', "Texture") + + def draw_label(self): + return "Simple texture" + +class PovrayFinishNode(Node, ObjectNodeTree): + '''Finish''' + bl_idname = 'PovrayFinishNode' + bl_label = 'Finish' + bl_icon = 'SOUND' + + def init(self, context): + + self.inputs.new('PovraySocketFloat_0_1', "Emission") + ambient=self.inputs.new('NodeSocketVector', "Ambient") + ambient.hide_value=True + diffuse=self.inputs.new('NodeSocketVector', "Diffuse") + diffuse.hide_value=True + specular=self.inputs.new('NodeSocketVector', "Highlight") + specular.hide_value=True + mirror=self.inputs.new('NodeSocketVector', "Mirror") + mirror.hide_value=True + iridescence=self.inputs.new('NodeSocketVector', "Iridescence") + iridescence.hide_value=True + subsurface=self.inputs.new('NodeSocketVector', "Translucency") + subsurface.hide_value=True + self.outputs.new('NodeSocketVector', "Finish") + + def draw_label(self): + return "Finish" + +class PovrayDiffuseNode(Node, ObjectNodeTree): + '''Diffuse''' + bl_idname = 'PovrayDiffuseNode' + bl_label = 'Diffuse' + bl_icon = 'SOUND' + + def init(self, context): + + intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity") + intensity.default_value=0.8 + albedo=self.inputs.new('NodeSocketBool', "Albedo") + albedo.default_value=False + brilliance=self.inputs.new('PovraySocketFloat_0_10', "Brilliance") + brilliance.default_value=1.8 + self.inputs.new('PovraySocketFloat_0_1', "Crand") + self.outputs.new('NodeSocketVector', "Diffuse") + + def draw_label(self): + return "Diffuse" + +class PovrayPhongNode(Node, ObjectNodeTree): + '''Phong''' + bl_idname = 'PovrayPhongNode' + bl_label = 'Phong' + bl_icon = 'SOUND' + + def init(self, context): + + albedo=self.inputs.new('NodeSocketBool', "Albedo") + intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity") + intensity.default_value=0.8 + phong_size=self.inputs.new('PovraySocketInt_0_256', "Size") + phong_size.default_value=60 + metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic") + + self.outputs.new('NodeSocketVector', "Phong") + + def draw_label(self): + return "Phong" + +class PovraySpecularNode(Node, ObjectNodeTree): + '''Specular''' + bl_idname = 'PovraySpecularNode' + bl_label = 'Specular' + bl_icon = 'SOUND' + + def init(self, context): + + albedo=self.inputs.new('NodeSocketBool', "Albedo") + intensity=self.inputs.new('PovraySocketFloat_0_1', "Intensity") + intensity.default_value=0.8 + roughness=self.inputs.new('PovraySocketFloat_0_1', "Roughness") + roughness.default_value=0.02 + metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic") + + self.outputs.new('NodeSocketVector', "Specular") + + def draw_label(self): + return "Specular" + +class PovrayMirrorNode(Node, ObjectNodeTree): + '''Mirror''' + bl_idname = 'PovrayMirrorNode' + bl_label = 'Mirror' + bl_icon = 'SOUND' + + def init(self, context): + + color=self.inputs.new('PovraySocketColor', "Color") + color.default_value=(1,1,1) + metallic=self.inputs.new('PovraySocketFloat_0_1', "Metallic") + metallic.default_value=1.0 + exponent=self.inputs.new('PovraySocketFloat_0_1', "Exponent") + exponent.default_value=1.0 + self.inputs.new('PovraySocketFloat_0_1', "Falloff") + self.inputs.new('NodeSocketBool', "Fresnel") + self.inputs.new('NodeSocketBool', "Conserve energy") + self.outputs.new('NodeSocketVector', "Mirror") + + def draw_label(self): + return "Mirror" + +class PovrayAmbientNode(Node, ObjectNodeTree): + '''Ambient''' + bl_idname = 'PovrayAmbientNode' + bl_label = 'Ambient' + bl_icon = 'SOUND' + + def init(self, context): + + self.inputs.new('PovraySocketColor', "Ambient") + + self.outputs.new('NodeSocketVector', "Ambient") + + def draw_label(self): + return "Ambient" + +class PovrayIridescenceNode(Node, ObjectNodeTree): + '''Iridescence''' + bl_idname = 'PovrayIridescenceNode' + bl_label = 'Iridescence' + bl_icon = 'SOUND' + + def init(self, context): + + amount=self.inputs.new('NodeSocketFloat', "Amount") + amount.default_value=0.25 + thickness=self.inputs.new('NodeSocketFloat', "Thickness") + thickness.default_value=1 + self.inputs.new('NodeSocketFloat', "Turbulence") + + self.outputs.new('NodeSocketVector', "Iridescence") + + def draw_label(self): + return "Iridescence" + +class PovraySubsurfaceNode(Node, ObjectNodeTree): + '''Subsurface''' + bl_idname = 'PovraySubsurfaceNode' + bl_label = 'Subsurface' + bl_icon = 'SOUND' + + def init(self, context): + + translucency=self.inputs.new('NodeSocketColor', "Translucency") + translucency.default_value=(0,0,0,1) + energy=self.inputs.new('PovraySocketInt_0_256', "Energy") + energy.default_value=20 + self.outputs.new('NodeSocketVector', "Translucency") + + def draw_buttons(self, context, layout): + scene=context.scene + layout.prop(scene.pov, "sslt_enable",text="SSLT") + + + def draw_buttons_ext(self, context, layout): + scene=context.scene + layout.prop(scene.pov, "sslt_enable",text="SSLT") + + def draw_label(self): + return "Subsurface" + +##################################################################################################### + +class PovrayMappingNode(Node, ObjectNodeTree): + '''Mapping''' + bl_idname = 'PovrayMappingNode' + bl_label = 'Mapping' + bl_icon = 'SOUND' + + warp_type = EnumProperty( + name="Warp Types", + description="Select the type of warp", + items=( ('cubic', "Cubic", ""), ('cylindrical', "Cylindrical", ""),('planar', "Planar", ""), + ('spherical', "Spherical", ""),('toroidal', "Toroidal", ""), + ('uv_mapping', "UV", ""), + ('NONE', "None", "No indentation")), + default='NONE') + + warp_orientation = EnumProperty( + name="Warp Orientation", + description="Select the orientation of warp", + items=(('x', "X", ""), ('y', "Y", ""), ('z', "Z", "")), + default='y') + + warp_dist_exp = FloatProperty( + name="Distance exponent", + description="Distance exponent", + min=0.0, max=100.0, default=1.0) + + warp_tor_major_radius = FloatProperty( + name="Major radius", + description="Torus is distance from major radius", + min=0.0, max=5.0, default=1.0) + + def init(self, context): + self.outputs.new('NodeSocketVector', "Mapping") + + def draw_buttons(self, context, layout): + + column=layout.column() + column.prop(self,"warp_type",text="Warp type") + if self.warp_type in {'toroidal','spherical','cylindrical','planar'}: + column.prop(self,"warp_orientation",text="Orientation") + column.prop(self,"warp_dist_exp",text="Exponent") + if self.warp_type=='toroidal': + column.prop(self,"warp_tor_major_radius",text="Major R") + + def draw_buttons_ext(self, context, layout): + + column=layout.column() + column.prop(self,"warp_type",text="Warp type") + if self.warp_type in {'toroidal','spherical','cylindrical','planar'}: + column.prop(self,"warp_orientation",text="Orientation") + column.prop(self,"warp_dist_exp",text="Exponent") + if self.warp_type=='toroidal': + column.prop(self,"warp_tor_major_radius",text="Major R") + + def draw_label(self): + return "Mapping" + +class PovrayMultiplyNode(Node, ObjectNodeTree): + '''Multiply''' + bl_idname = 'PovrayMultiplyNode' + bl_label = 'Multiply' + bl_icon = 'SOUND' + + amount_x = FloatProperty( + name="X", + description="Number of repeats", + min=1.0, max=10000.0, default=1.0) + + amount_y = FloatProperty( + name="Y", + description="Number of repeats", + min=1.0, max=10000.0, default=1.0) + + amount_z = FloatProperty( + name="Z", + description="Number of repeats", + min=1.0, max=10000.0, default=1.0) + + + def init(self, context): + self.outputs.new('NodeSocketVector', "Amount") + + def draw_buttons(self, context, layout): + + column=layout.column() + column.label("Amount") + row=column.row(align=True) + row.prop(self,"amount_x") + row.prop(self,"amount_y") + row.prop(self,"amount_z") + + def draw_buttons_ext(self, context, layout): + + column=layout.column() + column.label("Amount") + row=column.row(align=True) + row.prop(self,"amount_x") + row.prop(self,"amount_y") + row.prop(self,"amount_z") + + def draw_label(self): + return "Multiply" + +class PovrayTransformNode(Node, ObjectNodeTree): + '''Transform''' + bl_idname = 'PovrayTransformNode' + bl_label = 'Transform' + bl_icon = 'SOUND' + + def init(self, context): + + self.inputs.new('PovraySocketFloatUnlimited', "Translate x") + self.inputs.new('PovraySocketFloatUnlimited', "Translate y") + self.inputs.new('PovraySocketFloatUnlimited', "Translate z") + self.inputs.new('PovraySocketFloatUnlimited', "Rotate x") + self.inputs.new('PovraySocketFloatUnlimited', "Rotate y") + self.inputs.new('PovraySocketFloatUnlimited', "Rotate z") + sX = self.inputs.new('PovraySocketFloatUnlimited', "Scale x") + sX.default_value = 1.0 + sY = self.inputs.new('PovraySocketFloatUnlimited', "Scale y") + sY.default_value = 1.0 + sZ = self.inputs.new('PovraySocketFloatUnlimited', "Scale z") + sZ.default_value = 1.0 + + self.outputs.new('NodeSocketVector', "Transform") + + def draw_label(self): + return "Transform" + +class PovrayValueNode(Node, ObjectNodeTree): + '''Value''' + bl_idname = 'PovrayValueNode' + bl_label = 'Value' + bl_icon = 'SOUND' + + def init(self, context): + + self.outputs.new('PovraySocketUniversal', "Value") + + def draw_label(self): + return "Value" + +class PovrayModifierNode(Node, ObjectNodeTree): + '''Modifier''' + bl_idname = 'PovrayModifierNode' + bl_label = 'Modifier' + bl_icon = 'SOUND' + + def init(self, context): + + turb_x=self.inputs.new('PovraySocketFloat_0_10', "Turb X") + turb_x.default_value=0.1 + turb_y=self.inputs.new('PovraySocketFloat_0_10', "Turb Y") + turb_y.default_value=0.1 + turb_z=self.inputs.new('PovraySocketFloat_0_10', "Turb Z") + turb_z.default_value=0.1 + octaves=self.inputs.new('PovraySocketInt_1_9', "Octaves") + octaves.default_value=1 + lambat=self.inputs.new('PovraySocketFloat_0_10', "Lambda") + lambat.default_value=2.0 + omega=self.inputs.new('PovraySocketFloat_0_10', "Omega") + omega.default_value=0.5 + freq=self.inputs.new('PovraySocketFloat_0_10', "Frequency") + freq.default_value=2.0 + self.inputs.new('PovraySocketFloat_0_10', "Phase") + + self.outputs.new('NodeSocketVector', "Modifier") + + def draw_label(self): + return "Modifier" + +class PovrayPigmentNode(Node, ObjectNodeTree): + '''Pigment''' + bl_idname = 'PovrayPigmentNode' + bl_label = 'Color' + + def init(self, context): + + color = self.inputs.new('PovraySocketColor', "Color") + color.default_value = (1,1,1) + povfilter = self.inputs.new('PovraySocketFloat_0_1', "Filter") + transmit = self.inputs.new('PovraySocketFloat_0_1', "Transmit") + self.outputs.new('NodeSocketColor', "Pigment") + + def draw_label(self): + return "Color" + +class PovrayColorImageNode(Node, ObjectNodeTree): + '''ColorImage''' + bl_idname = 'PovrayColorImageNode' + bl_label = 'Image map' + + map_type = bpy.props.EnumProperty( + name="Map type", + description="", + items=( ('uv_mapping', "UV", ""), + ('0', "Planar", "Default planar mapping."), + ('1', "Spherical", "Spherical mapping."), + ('2', "Cylindrical", "Cylindrical mapping."), + ('5', "Torroidal", "Torus or donut shaped mapping.")), + default='0') + image = StringProperty(maxlen=1024) # , subtype="FILE_PATH" + interpolate = EnumProperty( + name="Interpolate", + description="Adding the interpolate keyword can smooth the jagged look of a bitmap.", + items=(('2', "Bilinear", "Gives bilinear interpolation."), + ('4', "Normalized", "Gives normalized distance.")), + default='2') + premultiplied = BoolProperty(default=False) + once = BoolProperty(description="Not to repeat.", default=False) + + def init(self, context): + + gamma=self.inputs.new('PovraySocketFloat_000001_10', "Gamma") + gamma.default_value=2.0 + transmit=self.inputs.new('PovraySocketFloat_0_1', "Transmit") + povfilter=self.inputs.new('PovraySocketFloat_0_1', "Filter") + mapping=self.inputs.new('NodeSocketVector', "Mapping") + mapping.hide_value=True + transform=self.inputs.new('NodeSocketVector', "Transform") + transform.hide_value=True + modifier=self.inputs.new('NodeSocketVector', "Modifier") + modifier.hide_value=True + + self.outputs.new('NodeSocketColor', "Pigment") + + def draw_buttons(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + row=column.row() + row.prop(self,"premultiplied",text="Premul") + row.prop(self,"once",text="Once") + + def draw_buttons_ext(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + row=column.row() + row.prop(self,"premultiplied",text="Premul") + row.prop(self,"once",text="Once") + + def draw_label(self): + return "Image map" + +class PovrayBumpMapNode(Node, ObjectNodeTree): + '''BumpMap''' + bl_idname = 'PovrayBumpMapNode' + bl_label = 'Bump map' + bl_icon = 'SOUND' + + map_type = bpy.props.EnumProperty( + name="Map type", + description="", + items=( ('uv_mapping', "UV", ""), + ('0', "Planar", "Default planar mapping."), + ('1', "Spherical", "Spherical mapping."), + ('2', "Cylindrical", "Cylindrical mapping."), + ('5', "Torroidal", "Torus or donut shaped mapping.")), + default='0') + image = StringProperty(maxlen=1024) # , subtype="FILE_PATH" + interpolate = EnumProperty( + name="Interpolate", + description="Adding the interpolate keyword can smooth the jagged look of a bitmap.", + items=(('2', "Bilinear", "Gives bilinear interpolation."), + ('4', "Normalized", "Gives normalized distance.")), + default='2') + once = BoolProperty(description="Not to repeat.", default=False) + + def init(self, context): + + self.inputs.new('PovraySocketFloat_0_10', "Normal") + mapping=self.inputs.new('NodeSocketVector', "Mapping") + mapping.hide_value=True + transform=self.inputs.new('NodeSocketVector', "Transform") + transform.hide_value=True + modifier=self.inputs.new('NodeSocketVector', "Modifier") + modifier.hide_value=True + + normal=self.outputs.new('NodeSocketFloat', "Normal") + normal.hide_value=True + + def draw_buttons(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + column.prop(self,"once",text="Once") + + def draw_buttons_ext(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + column.prop(self,"once",text="Once") + + def draw_label(self): + return "Bump Map" + +class PovrayImagePatternNode(Node, ObjectNodeTree): + '''ImagePattern''' + bl_idname = 'PovrayImagePatternNode' + bl_label = 'Image pattern' + bl_icon = 'SOUND' + + map_type = bpy.props.EnumProperty( + name="Map type", + description="", + items=( ('uv_mapping', "UV", ""), + ('0', "Planar", "Default planar mapping."), + ('1', "Spherical", "Spherical mapping."), + ('2', "Cylindrical", "Cylindrical mapping."), + ('5', "Torroidal", "Torus or donut shaped mapping.")), + default='0') + image = StringProperty(maxlen=1024) # , subtype="FILE_PATH" + interpolate = EnumProperty( + name="Interpolate", + description="Adding the interpolate keyword can smooth the jagged look of a bitmap.", + items=(('2', "Bilinear", "Gives bilinear interpolation."), + ('4', "Normalized", "Gives normalized distance.")), + default='2') + premultiplied = BoolProperty(default=False) + once = BoolProperty(description="Not to repeat.", default=False) + use_alpha = BoolProperty(default=True) + def init(self, context): + + gamma=self.inputs.new('PovraySocketFloat_000001_10', "Gamma") + gamma.default_value=2.0 + + self.outputs.new('PovraySocketPattern', "Pattern") + + def draw_buttons(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + row=column.row() + row.prop(self,"premultiplied",text="Premul") + row.prop(self,"once",text="Once") + column.prop(self,"use_alpha",text="Use alpha") + + def draw_buttons_ext(self, context, layout): + + column=layout.column() + im=None + for image in bpy.data.images: + if image.name == self.image: + im=image + split = column.split(percentage=0.8,align=True) + split.prop_search(self,"image",context.blend_data,"images",text="") + split.operator("pov.imageopen",text="",icon="FILESEL") + if im != None: + column.prop(im,"source",text="") + column.prop(self,"map_type",text="") + column.prop(self,"interpolate",text="") + row=column.row() + row.prop(self,"premultiplied",text="Premul") + row.prop(self,"once",text="Once") + + def draw_label(self): + return "Image pattern" + +class ShaderPatternNode(Node, ObjectNodeTree): + '''Pattern''' + bl_idname = 'ShaderPatternNode' + bl_label = 'Other patterns' + + pattern = EnumProperty( + name="Pattern", + description="Agate, Crackle, Gradient, Pavement, Spiral, Tiling", + items=(('agate', "Agate", ""),('crackle', "Crackle", ""),('gradient', "Gradient", ""), + ('pavement', "Pavement", ""), + ('spiral1', "Spiral 1", ""), + ('spiral2', "Spiral 2", ""), + ('tiling', "Tiling", "")), + default='agate') + + agate_turb = FloatProperty( + name="Agate turb", + description="Agate turbulence", + min=0.0, max=100.0, default=0.5) + + crackle_form_x = FloatProperty( + name="X", + description="Form vector X", + min=-150.0, max=150.0, default=-1) + + crackle_form_y = FloatProperty( + name="Y", + description="Form vector Y", + min=-150.0, max=150.0, default=1) + + crackle_form_z = FloatProperty( + name="Z", + description="Form vector Z", + min=-150.0, max=150.0, default=0) + + crackle_metric = FloatProperty( + name="Metric", + description="Crackle metric", + min=0.0, max=150.0, default=1) + + crackle_solid = BoolProperty( + name="Solid", + description="Crackle solid", + default=False) + + spiral_arms = FloatProperty( + name="Number", + description="", + min=0.0, max=256.0, default=2.0) + + tiling_number = IntProperty( + name="Number", + description="", + min=1, max=27, default=1) + + gradient_orient = EnumProperty( + name="Orient", + description="", + items=(('x', "X", ""), + ('y', "Y", ""), + ('z', "Z", "")), + default='x') + + def init(self, context): + + pat = self.outputs.new('PovraySocketPattern', "Pattern") + + def draw_buttons(self, context, layout): + + layout.prop(self, "pattern",text="") + if self.pattern=='agate': + layout.prop(self, "agate_turb") + if self.pattern=='crackle': + layout.prop(self, "crackle_metric") + layout.prop(self, "crackle_solid") + layout.label("Form:") + layout.prop(self, "crackle_form_x") + layout.prop(self, "crackle_form_y") + layout.prop(self, "crackle_form_z") + if self.pattern in {"spiral1","spiral2"}: + layout.prop(self, "spiral_arms") + if self.pattern in {'tiling'}: + layout.prop(self, "tiling_number") + if self.pattern in {'gradient'}: + layout.prop(self, "gradient_orient") + def draw_buttons_ext(self, context, layout): + pass + + def draw_label(self): + return "Other patterns" + +class ShaderTextureMapNode(Node, ObjectNodeTree): + '''Texture Map''' + bl_idname = 'ShaderTextureMapNode' + bl_label = 'Texture map' + + brick_size_x = FloatProperty( + name="X", + description="", + min=0.0000, max=1.0000, default=0.2500) + + brick_size_y = FloatProperty( + name="Y", + description="", + min=0.0000, max=1.0000, default=0.0525) + + brick_size_z = FloatProperty( + name="Z", + description="", + min=0.0000, max=1.0000, default=0.1250) + + brick_mortar = FloatProperty( + name="Mortar", + description="Mortar", + min=0.000, max=1.500, default=0.01) + + def init(self, context): + mat = bpy.context.object.active_material + self.inputs.new('PovraySocketPattern', "") + color = self.inputs.new('NodeSocketColor', "Color ramp") + color.hide_value = True + for i in range(0,4): + transform=self.inputs.new('PovraySocketTransform', "Transform") + transform.hide_value=True + number = mat.pov.inputs_number + for i in range(number): + self.inputs.new('PovraySocketTexture', "%s"%i) + + + self.outputs.new('PovraySocketTexture', "Texture") + + def draw_buttons(self, context, layout): + + if self.inputs[0].default_value =='brick': + layout.prop(self, "brick_mortar") + layout.label("Brick size:") + layout.prop(self, "brick_size_x") + layout.prop(self, "brick_size_y") + layout.prop(self, "brick_size_z") + + def draw_buttons_ext(self, context, layout): + + if self.inputs[0].default_value =='brick': + layout.prop(self, "brick_mortar") + layout.label("Brick size:") + layout.prop(self, "brick_size_x") + layout.prop(self, "brick_size_y") + layout.prop(self, "brick_size_z") + + def draw_label(self): + return "Texture map" + + +class ShaderNormalMapNode(Node, ObjectNodeTree): + '''Normal Map''' + bl_idname = 'ShaderNormalMapNode' + bl_label = 'Normal map' + + brick_size_x = FloatProperty( + name="X", + description="", + min=0.0000, max=1.0000, default=0.2500) + + brick_size_y = FloatProperty( + name="Y", + description="", + min=0.0000, max=1.0000, default=0.0525) + + brick_size_z = FloatProperty( + name="Z", + description="", + min=0.0000, max=1.0000, default=0.1250) + + brick_mortar = FloatProperty( + name="Mortar", + description="Mortar", + min=0.000, max=1.500, default=0.01) + + def init(self, context): + self.inputs.new('PovraySocketPattern', "") + normal = self.inputs.new('PovraySocketFloat_10', "Normal") + slope = self.inputs.new('PovraySocketMap', "Slope map") + for i in range(0,4): + transform=self.inputs.new('PovraySocketTransform', "Transform") + transform.hide_value=True + self.outputs.new('PovraySocketNormal', "Normal") + + def draw_buttons(self, context, layout): + #for i, inp in enumerate(self.inputs): + + if self.inputs[0].default_value =='brick': + layout.prop(self, "brick_mortar") + layout.label("Brick size:") + layout.prop(self, "brick_size_x") + layout.prop(self, "brick_size_y") + layout.prop(self, "brick_size_z") + + def draw_buttons_ext(self, context, layout): + + if self.inputs[0].default_value =='brick': + layout.prop(self, "brick_mortar") + layout.label("Brick size:") + layout.prop(self, "brick_size_x") + layout.prop(self, "brick_size_y") + layout.prop(self, "brick_size_z") + + def draw_label(self): + return "Normal map" + +class ShaderNormalMapEntryNode(Node, ObjectNodeTree): + '''Normal Map Entry''' + bl_idname = 'ShaderNormalMapEntryNode' + bl_label = 'Normal map entry' + + def init(self, context): + self.inputs.new('PovraySocketFloat_0_1', "Stop") + self.inputs.new('PovraySocketFloat_0_1', "Gray") + def draw_label(self): + return "Normal map entry" + +class IsoPropsNode(Node, CompositorNodeTree): + '''ISO Props''' + bl_idname = 'IsoPropsNode' + bl_label = 'Iso' + node_label = StringProperty(maxlen=1024) + def init(self, context): + ob = bpy.context.object + self.node_label = ob.name + textName = ob.pov.function_text + if textName: + text = bpy.data.texts[textName] + for line in text.lines: + split = line.body.split() + if split[0] == "#declare": + socket = self.inputs.new('NodeSocketFloat', "%s"%split[1]) + value = split[3].split(";") + value = value[0] + socket.default_value=float(value) + def draw_label(self): + return self.node_label + +class PovrayFogNode(Node, CompositorNodeTree): + '''Fog settings''' + bl_idname = 'PovrayFogNode' + bl_label = 'Fog' + def init(self, context): + color=self.inputs.new('NodeSocketColor', "Color") + color.default_value=(0.7,0.7,0.7,0.25) + self.inputs.new('PovraySocketFloat_0_1', "Filter") + distance = self.inputs.new('NodeSocketInt', "Distance") + distance.default_value=150 + self.inputs.new('NodeSocketBool', "Ground") + fog_offset=self.inputs.new('NodeSocketFloat', "Offset") + fog_alt=self.inputs.new('NodeSocketFloat', "Altitude") + turb = self.inputs.new('NodeSocketVector', "Turbulence") + turb_depth=self.inputs.new('PovraySocketFloat_0_10', "Depth") + turb_depth.default_value=0.5 + octaves=self.inputs.new('PovraySocketInt_1_9', "Octaves") + octaves.default_value=5 + lambdat=self.inputs.new('PovraySocketFloat_0_10', "Lambda") + lambdat.default_value=1.25 + omega=self.inputs.new('PovraySocketFloat_0_10', "Omega") + omega.default_value=0.35 + translate = self.inputs.new('NodeSocketVector', "Translate") + rotate = self.inputs.new('NodeSocketVector', "Rotate") + scale = self.inputs.new('NodeSocketVector', "Scale") + scale.default_value=(1,1,1) + def draw_label(self): + return "Fog" + +class PovraySlopeNode(Node, TextureNodeTree): + '''Output''' + bl_idname = 'PovraySlopeNode' + bl_label = 'Slope Map' + + def init(self, context): + self.use_custom_color = True + self.color = (0,0.2,0) + slope = self.inputs.new('PovraySocketSlope', "0") + slope = self.inputs.new('PovraySocketSlope', "1") + slopemap = self.outputs.new('PovraySocketMap', "Slope map") + output.hide_value = True + def draw_buttons(self, context, layout): + + layout.operator("pov.nodeinputadd") + row = layout.row() + row.label('Value') + row.label('Height') + row.label('Slope') + + def draw_buttons_ext(self, context, layout): + + layout.operator("pov.nodeinputadd") + row = layout.row() + row.label('Value') + row.label('Height') + row.label('Slope') + + def draw_label(self): + return "Slope Map" + +######################################## Texture nodes ############################### +class TextureOutputNode(Node, TextureNodeTree): + '''Output''' + bl_idname = 'TextureOutputNode' + bl_label = 'Color Map' + + def init(self, context): + tex = bpy.context.object.active_material.active_texture + num_sockets = int(tex.pov.density_lines/32) + for i in range(num_sockets): + color = self.inputs.new('NodeSocketColor', "%s"%i) + color.hide_value = True + + def draw_buttons(self, context, layout): + + layout.label("Color Ramps:") + + def draw_label(self): + return "Color Map" + + +################################################################################## +#################################Operators######################################## +################################################################################## + + +class NODE_OT_iso_add(bpy.types.Operator): + bl_idname = "pov.nodeisoadd" + bl_label = "Create iso props" + + def execute(self, context): + ob = bpy.context.object + if bpy.context.scene.use_nodes == False: + bpy.context.scene.use_nodes = True + tree = bpy.context.scene.node_tree + for node in tree.nodes: + if node.bl_idname == "IsoPropsNode" and node.label == ob.name: + tree.nodes.remove(node) + isonode = tree.nodes.new('IsoPropsNode') + isonode.location = (0,0) + isonode.label = ob.name + return {'FINISHED'} + +class NODE_OT_map_create(bpy.types.Operator): + bl_idname = "node.map_create" + bl_label = "Create map" + + def execute(self, context): + x = y = 0 + space = context.space_data + tree = space.edit_tree + for node in tree.nodes: + if node.select == True: + x,y = node.location + node.select=False + tmap = tree.nodes.new('ShaderTextureMapNode') + tmap.location = (x - 200,y) + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + def draw(self, context): + layout = self.layout + mat = context.object.active_material + layout.prop(mat.pov,"inputs_number") + +class NODE_OT_povray_node_texture_map_add(bpy.types.Operator): + bl_idname = "pov.nodetexmapadd" + bl_label = "Texture map" + + def execute(self, context): + tree=bpy.context.object.active_material.node_tree + tmap = tree.nodes.active + bpy.context.object.active_material.node_tree.nodes.active=tmap + el=tmap.color_ramp.elements.new(0.5) + for el in tmap.color_ramp.elements: + el.color=(0,0,0,1) + for inp in tmap.inputs: + tmap.inputs.remove(inp) + for outp in tmap.outputs: + tmap.outputs.remove(outp) + pattern=tmap.inputs.new('NodeSocketVector', "Pattern") + pattern.hide_value=True + for i in range(0,3): + tmap.inputs.new('NodeSocketColor', "Shader") + tmap.outputs.new('NodeSocketShader', "BSDF") + tmap.label="Texture Map" + return {'FINISHED'} + + +class NODE_OT_povray_node_output_add(bpy.types.Operator): + bl_idname = "pov.nodeoutputadd" + bl_label = "Output" + + def execute(self, context): + tree=bpy.context.object.active_material.node_tree + tmap = tree.nodes.new('ShaderNodeOutputMaterial') + bpy.context.object.active_material.node_tree.nodes.active=tmap + for inp in tmap.inputs: + tmap.inputs.remove(inp) + tmap.inputs.new('NodeSocketShader', "Surface") + tmap.label="Output" + return {'FINISHED'} + +class NODE_OT_povray_node_layered_add(bpy.types.Operator): + bl_idname = "pov.nodelayeredadd" + bl_label = "Layered material" + + def execute(self, context): + tree=bpy.context.object.active_material.node_tree + tmap = tree.nodes.new('ShaderNodeAddShader') + bpy.context.object.active_material.node_tree.nodes.active=tmap + tmap.label="Layered material" + return {'FINISHED'} + +class NODE_OT_povray_input_add(bpy.types.Operator): + bl_idname = "pov.nodeinputadd" + bl_label = "Add entry" + + def execute(self, context): + node=bpy.context.object.active_material.node_tree.nodes.active + if node.type in {'VALTORGB'}: + number=1 + for inp in node.inputs: + if inp.type=='SHADER': + number+=1 + node.inputs.new('NodeSocketShader', "%s"%number) + els=node.color_ramp.elements + pos1=els[len(els)-1].position + pos2=els[len(els)-2].position + pos=(pos1-pos2)/2+pos2 + el=els.new(pos) + + if node.bl_idname == 'PovraySlopeNode': + number=len(node.inputs) + node.inputs.new('PovraySocketSlope', "%s"%number) + + + return {'FINISHED'} + +class NODE_OT_povray_input_remove(bpy.types.Operator): + bl_idname = "pov.nodeinputremove" + bl_label = "Remove input" + + def execute(self, context): + node=bpy.context.object.active_material.node_tree.nodes.active + if node.type in {'VALTORGB','ADD_SHADER'}: + number=len(node.inputs)-1 + if number > 5: + inp=node.inputs[number] + node.inputs.remove(inp) + if node.type in {'VALTORGB'}: + els=node.color_ramp.elements + number=len(els)-2 + el=els[number] + els.remove(el) + return {'FINISHED'} + +class NODE_OT_povray_image_open(bpy.types.Operator): + bl_idname = "pov.imageopen" + bl_label = "Open" + + filepath = StringProperty( + name="File Path", + description="Open image", + maxlen=1024, + subtype='FILE_PATH', + ) + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + + def execute(self, context): + im=bpy.data.images.load(self.filepath) + node=context.object.active_material.node_tree.nodes.active + node.image = im.name + return {'FINISHED'} + + +# class TEXTURE_OT_povray_open_image(bpy.types.Operator): + # bl_idname = "pov.openimage" + # bl_label = "Open Image" + + # filepath = StringProperty( + # name="File Path", + # description="Open image", + # maxlen=1024, + # subtype='FILE_PATH', + # ) + + # def invoke(self, context, event): + # context.window_manager.fileselect_add(self) + # return {'RUNNING_MODAL'} + + # def execute(self, context): + # im=bpy.data.images.load(self.filepath) + # tex = context.texture + # tex.pov.image = im.name + # scene = context.scene + # scene.update() + # return {'FINISHED'} + +class PovrayPatternNode(bpy.types.Operator): + bl_idname = "pov.patternnode" + bl_label = "Pattern" + + add=True + + def execute(self, context): + space = context.space_data + tree = space.edit_tree + for node in tree.nodes: + node.select=False + if self.add==True: + tmap = tree.nodes.new('ShaderNodeValToRGB') + tmap.label="Pattern" + for inp in tmap.inputs: + tmap.inputs.remove(inp) + for outp in tmap.outputs: + tmap.outputs.remove(outp) + pattern = tmap.inputs.new('PovraySocketPattern', "Pattern") + pattern.hide_value = True + mapping=tmap.inputs.new('NodeSocketVector', "Mapping") + mapping.hide_value=True + transform=tmap.inputs.new('NodeSocketVector', "Transform") + transform.hide_value=True + modifier=tmap.inputs.new('NodeSocketVector', "Modifier") + modifier.hide_value=True + for i in range(0,2): + tmap.inputs.new('NodeSocketShader', "%s"%(i+1)) + tmap.outputs.new('NodeSocketShader', "Material") + tmap.outputs.new('NodeSocketColor', "Color") + tree.nodes.active=tmap + self.add=False + aNode=tree.nodes.active + aNode.select=True + v2d = context.region.view2d + x, y = v2d.region_to_view(self.x, self.y) + aNode.location = (x, y) + + def modal(self, context, event): + if event.type == 'MOUSEMOVE': + self.x = event.mouse_region_x + self.y = event.mouse_region_y + self.execute(context) + return {'RUNNING_MODAL'} + elif event.type == 'LEFTMOUSE': + return {'FINISHED'} + elif event.type in ('RIGHTMOUSE', 'ESC'): + return {'CANCELLED'} + + return {'RUNNING_MODAL'} + + def invoke(self, context, event): + context.window_manager.modal_handler_add(self) + return {'RUNNING_MODAL'} + +class UpdatePreviewMaterial(bpy.types.Operator): + '''Operator update preview material''' + bl_idname = "node.updatepreview" + bl_label = "Update preview" + + def execute(self, context): + scene=context.scene + ob=context.object + for obj in scene.objects: + if obj != ob: + scene.objects.active=obj + break + scene.objects.active=ob + + def modal(self, context, event): + if event.type == 'RIGHTMOUSE': + self.execute(context) + return {'FINISHED'} + return {'PASS_THROUGH'} + + def invoke(self, context, event): + context.window_manager.modal_handler_add(self) + return {'RUNNING_MODAL'} + +class UpdatePreviewKey(bpy.types.Operator): + '''Operator update preview keymap''' + bl_idname = "wm.updatepreviewkey" + bl_label = "Activate RMB" + @classmethod + def poll(cls, context): + conf = context.window_manager.keyconfigs.active + mapstr = "Node Editor" + map = conf.keymaps[mapstr] + try: + map.keymap_items["node.updatepreview"] + return False + except: + return True + + def execute(self, context): + conf = context.window_manager.keyconfigs.active + mapstr = "Node Editor" + map = conf.keymaps[mapstr] + map.keymap_items.new("node.updatepreview",type='RIGHTMOUSE',value="PRESS") + return {'FINISHED'} + +
\ No newline at end of file |