From 07d031412aa45b04998741f2810bb335ada228f9 Mon Sep 17 00:00:00 2001 From: Maurice Raybaud <mauriceraybaud@hotmail.fr> Date: Thu, 27 Feb 2014 22:53:01 +0100 Subject: [PATCH] *added: first implementation of procedural textures *fixed:packed textures *fixed:library objects --- render_povray/__init__.py | 469 +++++++++++++++++++- render_povray/render.py | 881 +++++++++++++++++++++++++++++++++----- render_povray/ui.py | 291 ++++++++++++- 3 files changed, 1525 insertions(+), 116 deletions(-) diff --git a/render_povray/__init__.py b/render_povray/__init__.py index 1aa72f179..15184b670 100644 --- a/render_povray/__init__.py +++ b/render_povray/__init__.py @@ -20,19 +20,17 @@ bl_info = { "name": "POV-Ray 3.7", - "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud, " - "Constantin Rahn, Bastien Montagne", + "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud, Constantin Rahn, Bastien Montagne", "version": (0, 0, 9), "blender": (2, 57, 0), "location": "Render > Engine > POV-Ray 3.7", "description": "Basic POV-Ray 3.7 integration for blender", - "warning": "both POV-Ray 3.7 and this script are beta", + "warning": "this script is RC", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Render/POV-Ray", + "Scripts/Render/POV-Ray", "tracker_url": "https://developer.blender.org/T23145", "category": "Render"} - if "bpy" in locals(): import imp imp.reload(ui) @@ -43,6 +41,7 @@ else: import bpy from bpy.types import (AddonPreferences, PropertyGroup, + Operator, ) from bpy.props import (StringProperty, BoolProperty, @@ -56,7 +55,8 @@ else: from . import render from . import update_files - +def string_strip_hyphen(name): + return name.replace("-", "") ############################################################################### # Scene POV properties. @@ -67,6 +67,10 @@ class RenderPovSettingsScene(PropertyGroup): name="Enable Tempfiles", description="Enable the OS-Tempfiles. Otherwise set the path where to save the files", default=True) + pov_editor = BoolProperty( + name="POV-Ray editor", + description="Don't Close POV-Ray editor after rendering (Overriden by /EXIT command)", + default=False) deletefiles_enable = BoolProperty( name="Delete files", description="Delete files after rendering. Doesn't work with the image", @@ -419,7 +423,452 @@ class RenderPovSettingsTexture(PropertyGroup): # "it points at. pigment {} expected", # default="") - + + + tex_pattern_type = EnumProperty( + name="Texture_Type", + description="Choose between Blender or POV-Ray parameters to specify texture", + items= (('agate', 'Agate', '','PLUGIN', 0), ('aoi', 'Aoi', '', 'PLUGIN', 1), + ('average', 'Average', '', 'PLUGIN', 2), ('boxed', 'Boxed', '', 'PLUGIN', 3), + ('bozo', 'Bozo', '', 'PLUGIN', 4), ('bumps', 'Bumps', '', 'PLUGIN', 5), + ('cells', 'Cells', '', 'PLUGIN', 6), ('crackle', 'Crackle', '', 'PLUGIN', 7), + ('cubic', 'Cubic', '', 'PLUGIN', 8), ('cylindrical', 'Cylindrical', '', 'PLUGIN', 9), + ('density_file', 'Density', '(.df3)', 'PLUGIN', 10), + ('dents', 'Dents', '', 'PLUGIN', 11), + ('fractal', 'Fractal', '', 'PLUGIN', 12), + ('function', 'Function', '', 'PLUGIN', 13), + ('gradient', 'Gradient', '', 'PLUGIN', 14), ('granite', 'Granite', '', 'PLUGIN', 15), + ('image_pattern', 'Image pattern', '', 'PLUGIN', 16), + ('leopard', 'Leopard', '', 'PLUGIN', 17), + ('marble', 'Marble', '', 'PLUGIN', 18), ('onion', 'Onion', '', 'PLUGIN', 19), + ('pigment_pattern', 'pigment pattern', '', 'PLUGIN', 20), + ('planar', 'Planar', '', 'PLUGIN', 21), ('quilted', 'Quilted', '', 'PLUGIN', 22), + ('radial', 'Radial', '', 'PLUGIN', 23), ('ripples', 'Ripples', '', 'PLUGIN', 24), + ('slope', 'Slope', '', 'PLUGIN', 25), + ('spherical', 'Spherical', '', 'PLUGIN', 26), ('spiral1', 'Spiral1', '', 'PLUGIN', 27), + ('spiral2', 'Spiral2', '', 'PLUGIN', 28), ('spotted', 'Spotted', '', 'PLUGIN', 29), + ('waves', 'Waves', '', 'PLUGIN', 30), ('wood', 'Wood', '', 'PLUGIN', 31), + ('wrinkles', 'Wrinkles', '', 'PLUGIN', 32), ('brick', "Brick", "", 'PLUGIN', 33), + ('checker', "Checker", "", 'PLUGIN', 34), ('hexagon', "Hexagon", "", 'PLUGIN', 35), + ('object', "Mesh", "", 'PLUGIN', 36), ('emulator', "Internal Emulator", "", 'PLUG', 37)), + default='emulator', + ) + + magnet_style = EnumProperty( + name="Magnet style", + description="magnet or julia", + items=(('mandel', "Mandelbrot", ""),('julia', "Julia", "")), + default='julia') + + magnet_type = IntProperty( + name="Magnet_type", + description="1 or 2", + min=1, max=2, default=2) + + warp_types = EnumProperty( + name="Warp Types", + description="Select the type of warp", + items=(('PLANAR', "Planar", ""), ('CUBIC', "Cubic", ""), ('SPHERICAL', "Spherical", ""), + ('TOROIDAL', "Toroidal", ""), ('CYLINDRICAL', "Cylindrical", ""),('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') + + wave_type = EnumProperty( + name="Waves type", + description="Select the type of waves", + items=(('ramp', "Ramp", ""), ('sine', "Sine", ""), ('scallop', "Scallop", ""), ('cubic', "Cubic", ""), + ('poly', "Poly", ""), ('triangle', 'Triangle', "")), + default='ramp') + + gen_noise = IntProperty( + name="Noise Generators", + description="Noise Generators", + min=1, max=3, default=1) + + 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) + + + warp_turbulence_x = FloatProperty( + name="Turbulence X", + description="Turbulence X", + min=0.0, max=5.0, default=0.0) + + warp_turbulence_y = FloatProperty( + name="Turbulence Y", + description="Turbulence Y", + min=0.0, max=5.0, default=0.0) + + warp_turbulence_z = FloatProperty( + name="Turbulence Z", + description="Turbulence Z", + min=0.0, max=5.0, default=0.0) + + modifier_octaves = IntProperty( + name="Turbulence octaves", + description="Turbulence octaves", + min=1, max=10, default=1) + + modifier_lambda = FloatProperty( + name="Turbulence lambda", + description="Turbulence lambda", + min=0.0, max=5.0, default=1.00) + + modifier_omega = FloatProperty( + name="Turbulence omega", + description="Turbulence omega", + min=0.0, max=10.0, default=1.00) + + modifier_phase = FloatProperty( + name="Phase", + description="The phase value causes the map entries to be shifted so that the map starts and ends at a different place.", + min=0.0, max=2.0, default=0.0) + + modifier_frequency = FloatProperty( + name="Frequency", + description="The frequency keyword adjusts the number of times that a color map repeats over one cycle of a pattern.", + min=0.0, max=25.0, default=2.0) + + modifier_turbulence = FloatProperty( + name="Turbulence", + description="Turbulence", + min=0.0, max=5.0, default=2.0) + + modifier_numbers = IntProperty( + name="Numbers", + description="Numbers", + min=1, max=27, default=2) + + modifier_control0 = IntProperty( + name="Control0", + description="Control0", + min=0, max=100, default=1) + + modifier_control1 = IntProperty( + name="Control1", + description="Control1", + min=0, max=100, default=1) + + brick_size_x = FloatProperty( + name="Brick size x", + description="", + min=0.0000, max=1.0000, default=0.2500) + + brick_size_y = FloatProperty( + name="Brick size y", + description="", + min=0.0000, max=1.0000, default=0.0525) + + brick_size_z = FloatProperty( + name="Brick size 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) + + julia_complex_1 = FloatProperty( + name="Julia Complex 1", + description="", + min=0.000, max=1.500, default=0.360) + + julia_complex_2 = FloatProperty( + name="Julia Complex 2", + description="", + min=0.000, max=1.500, default=0.250) + + f_iter = IntProperty( + name="Fractal Iteration", + description="", + min=0, max=100, default=20) + + f_exponent = IntProperty( + name="Fractal Exponent", + description="", + min=2, max=33, default=2) + + f_ior = IntProperty( + name="Fractal Interior", + description="", + min=1, max=6, default=1) + + f_ior_fac = FloatProperty( + name="Fractal Interior Factor", + description="", + min=0.0, max=10.0, default=1.0) + + f_eor = IntProperty( + name="Fractal Exterior", + description="", + min=1, max=8, default=1) + + f_eor_fac = FloatProperty( + name="Fractal Exterior Factor", + description="", + min=0.0, max=10.0, default=1.0) + + grad_orient_x= IntProperty( + name="Gradient orientation X", + description="", + min=0, max=1, default=0) + + grad_orient_y= IntProperty( + name="Gradient orientation Y", + description="", + min=0, max=1, default=1) + + grad_orient_z= IntProperty( + name="Gradient orientation Z", + description="", + min=0, max=1, default=0) + + pave_sides = EnumProperty( + name="Pavement sides", + description="", + items=(('3', "3", ""), ('4', "4", ""), ('6', "6", "")), + default='3') + + pave_pat_2= IntProperty( + name="Pavement pattern 2", + description="maximum: 2", + min=1, max=2, default=2) + + pave_pat_3= IntProperty( + name="Pavement pattern 3", + description="maximum: 3", + min=1, max=3, default=3) + + pave_pat_4= IntProperty( + name="Pavement pattern 4", + description="maximum: 4", + min=1, max=4, default=4) + + pave_pat_5= IntProperty( + name="Pavement pattern 5", + description="maximum: 5", + min=1, max=5, default=5) + + pave_pat_7= IntProperty( + name="Pavement pattern 7", + description="maximum: 7", + min=1, max=7, default=7) + + pave_pat_12= IntProperty( + name="Pavement pattern 12", + description="maximum: 12", + min=1, max=12, default=12) + + pave_pat_22= IntProperty( + name="Pavement pattern 22", + description="maximum: 22", + min=1, max=22, default=22) + + pave_pat_35= IntProperty( + name="Pavement pattern 35", + description="maximum: 35", + min=1, max=35, default=35) + + pave_tiles= IntProperty( + name="Pavement tiles", + description="If sides = 6, maximum tiles 5!!!", + min=1, max=6, default=1) + + pave_form= IntProperty( + name="Pavement form", + description="", + min=0, max=4, default=0) + + #########FUNCTIONS######################################################################################################################### + #########FUNCTIONS######################################################################################################################### + + func_list = EnumProperty( + name="Functions", + description="Select the function for create pattern", + items=(('NONE', "None", "No indentation"), + ("f_algbr_cyl1","Algbr cyl1",""), ("f_algbr_cyl2","Algbr cyl2",""), + ("f_algbr_cyl3","Algbr cyl3",""), ("f_algbr_cyl4","Algbr cyl4",""), + ("f_bicorn","Bicorn",""), ("f_bifolia","Bifolia",""), + ("f_blob","Blob",""), ("f_blob2","Blob2",""), + ("f_boy_surface","Boy surface",""), ("f_comma","Comma",""), + ("f_cross_ellipsoids","Cross ellipsoids",""), ("f_crossed_trough","Crossed trough",""), + ("f_cubic_saddle","Cubic saddle",""), ("f_cushion","Cushion",""), + ("f_devils_curve","Devils curve",""), ("f_devils_curve_2d","Devils curve 2d",""), + ("f_dupin_cyclid","Dupin cyclid",""), ("f_ellipsoid","Ellipsoid",""), + ("f_enneper","Enneper",""), ("f_flange_cover","Flange cover",""), + ("f_folium_surface","Folium surface",""), ("f_folium_surface_2d","Folium surface 2d",""), + ("f_glob","Glob",""), ("f_heart","Heart",""), + ("f_helical_torus","Helical torus",""), ("f_helix1","Helix1",""), + ("f_helix2","Helix2",""), ("f_hex_x","Hex x",""), + ("f_hex_y","Hex y",""), ("f_hetero_mf","Hetero mf",""), + ("f_hunt_surface","Hunt surface",""), ("f_hyperbolic_torus","Hyperbolic torus",""), + ("f_isect_ellipsoids","Isect ellipsoids",""), ("f_kampyle_of_eudoxus","Kampyle of eudoxus",""), + ("f_kampyle_of_eudoxus_2d","Kampyle of eudoxus 2d",""), ("f_klein_bottle","Klein bottle",""), + ("f_kummer_surface_v1","Kummer surface v1",""), ("f_kummer_surface_v2","Kummer surface v2",""), + ("f_lemniscate_of_gerono","Lemniscate of gerono",""), ("f_lemniscate_of_gerono_2d","Lemniscate of gerono 2d",""), + ("f_mesh1","Mesh1",""), ("f_mitre","Mitre",""), + ("f_nodal_cubic","Nodal cubic",""), ("f_noise3d","Noise3d",""), + ("f_noise_generator","Noise generator",""), ("f_odd","Odd",""), + ("f_ovals_of_cassini","Ovals of cassini",""), ("f_paraboloid","Paraboloid",""), + ("f_parabolic_torus","Parabolic torus",""), ("f_ph","Ph",""), + ("f_pillow","Pillow",""), ("f_piriform","Piriform",""), + ("f_piriform_2d","Piriform 2d",""), ("f_poly4","Poly4",""), + ("f_polytubes","Polytubes",""), ("f_quantum","Quantum",""), + ("f_quartic_paraboloid","Quartic paraboloid",""), ("f_quartic_saddle","Quartic saddle",""), + ("f_quartic_cylinder","Quartic cylinder",""), ("f_r","R",""), + ("f_ridge","Ridge",""), ("f_ridged_mf","Ridged mf",""), + ("f_rounded_box","Rounded box",""), ("f_sphere","Sphere",""), + ("f_spikes","Spikes",""), ("f_spikes_2d","Spikes 2d",""), + ("f_spiral","Spiral",""), ("f_steiners_roman","Steiners roman",""), + ("f_strophoid","Strophoid",""), ("f_strophoid_2d","Strophoid 2d",""), + ("f_superellipsoid","Superellipsoid",""), ("f_th","Th",""), + ("f_torus","Torus",""), ("f_torus2","Torus2",""), + ("f_torus_gumdrop","Torus gumdrop",""), ("f_umbrella","Umbrella",""), + ("f_witch_of_agnesi","Witch of agnesi",""), ("f_witch_of_agnesi_2d","Witch of agnesi 2d","")), + + default='NONE') + + func_x = FloatProperty( + name="FX", + description="", + min=0.0, max=25.0, default=1.0) + + func_plus_x = EnumProperty( + name="Func plus x", + description="", + items=(('NONE', "None", ""), ('increase', "*", ""), ('plus', "+", "")), + default='NONE') + + func_y = FloatProperty( + name="FY", + description="", + min=0.0, max=25.0, default=1.0) + + func_plus_y = EnumProperty( + name="Func plus y", + description="", + items=(('NONE', "None", ""), ('increase', "*", ""), ('plus', "+", "")), + default='NONE') + + func_z = FloatProperty( + name="FZ", + description="", + min=0.0, max=25.0, default=1.0) + + func_plus_z = EnumProperty( + name="Func plus z", + description="", + items=(('NONE', "None", ""), ('increase', "*", ""), ('plus', "+", "")), + default='NONE') + + func_P0 = FloatProperty( + name="P0", + description="", + min=0.0, max=25.0, default=1.0) + + func_P1 = FloatProperty( + name="P1", + description="", + min=0.0, max=25.0, default=1.0) + + func_P2 = FloatProperty( + name="P2", + description="", + min=0.0, max=25.0, default=1.0) + + func_P3 = FloatProperty( + name="P3", + description="", + min=0.0, max=25.0, default=1.0) + + func_P4 = FloatProperty( + name="P4", + description="", + min=0.0, max=25.0, default=1.0) + + func_P5 = FloatProperty( + name="P5", + description="", + min=0.0, max=25.0, default=1.0) + + func_P6 = FloatProperty( + name="P6", + description="", + min=0.0, max=25.0, default=1.0) + + func_P7 = FloatProperty( + name="P7", + description="", + min=0.0, max=25.0, default=1.0) + + func_P8 = FloatProperty( + name="P8", + description="", + min=0.0, max=25.0, default=1.0) + + func_P9 = FloatProperty( + name="P9", + description="", + min=0.0, max=25.0, default=1.0) + + ######################################### + tex_rot_x = FloatProperty( + name="Rotate X", + description="", + min=-180.0, max=180.0, default=0.0) + + tex_rot_y = FloatProperty( + name="Rotate Y", + description="", + min=-180.0, max=180.0, default=0.0) + + tex_rot_z = FloatProperty( + name="Rotate Z", + description="", + min=-180.0, max=180.0, default=0.0) + + tex_mov_x = FloatProperty( + name="Move X", + description="", + min=-100000.0, max=100000.0, default=0.0) + + tex_mov_y = FloatProperty( + name="Move Y", + description="", + min=-100000.0, max=100000.0, default=0.0) + + tex_mov_z = FloatProperty( + name="Move Z", + description="", + min=-100000.0, max=100000.0, default=0.0) + + tex_scale_x = FloatProperty( + name="Scale X", + description="", + min=0.0, max=10000.0, default=1.0) + + tex_scale_y = FloatProperty( + name="Scale Y", + description="", + min=0.0, max=10000.0, default=1.0) + + tex_scale_z = FloatProperty( + name="Scale Z", + description="", + min=0.0, max=10000.0, default=1.0) ############################################################################### # Object POV properties. ############################################################################### @@ -530,10 +979,12 @@ class PovrayPreferences(AddonPreferences): layout = self.layout layout.prop(self, "filepath_povray") + + def register(): bpy.utils.register_module(__name__) - + #bpy.types.TEXTURE_PT_context_texture.prepend(TEXTURE_PT_povray_type) bpy.types.Scene.pov = PointerProperty(type=RenderPovSettingsScene) bpy.types.Material.pov = PointerProperty(type=RenderPovSettingsMaterial) bpy.types.Texture.pov = PointerProperty(type=RenderPovSettingsTexture) @@ -544,7 +995,7 @@ def register(): def unregister(): bpy.utils.unregister_module(__name__) - + #bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_povray_type) del bpy.types.Scene.pov del bpy.types.Material.pov del bpy.types.Texture.pov diff --git a/render_povray/render.py b/render_povray/render.py index 05d7cabfb..9b0765012 100644 --- a/render_povray/render.py +++ b/render_povray/render.py @@ -26,6 +26,9 @@ import time from math import atan, pi, degrees, sqrt import re import random +import platform# +import subprocess# +from bpy.types import(Operator)#all added for render preview ##############################SF########################### ##############find image texture @@ -42,8 +45,8 @@ def imageFormat(imgF): 'SYS': "sys", 'TIFF': "tiff", 'TIF': "tiff", - 'EXR': "exr", # POV3.7 Only! - 'HDR': "hdr", # POV3.7 Only! --MR + 'EXR': "exr", + 'HDR': "hdr", }.get(os.path.splitext(imgF)[-1].upper(), "") if not ext: @@ -57,7 +60,7 @@ def imgMap(ts): if ts.mapping == 'FLAT': image_map = "map_type 0 " elif ts.mapping == 'SPHERE': - image_map = "map_type 1 " # map_type 7 in megapov + image_map = "map_type 1 " elif ts.mapping == 'TUBE': image_map = "map_type 2 " @@ -142,16 +145,488 @@ def safety(name, Level): ##############end safety string name material ##############################EndSF########################### -def is_renderable(scene, ob): - return (ob.is_visible(scene) and not ob.hide_render) +def is_renderable(ob): + return (ob.hide_render==False) -def renderable_objects(scene): - return [ob for ob in scene.objects if is_renderable(scene, ob)] +def renderable_objects(): + return [ob for ob in bpy.data.objects if is_renderable(ob)] tabLevel = 0 +unpacked_images=[] + +def exportPattern(texture): + tex=texture + pat = tex.pov + PATname = "PAT_%s"%string_strip_hyphen(bpy.path.clean_name(tex.name)) + mappingDif = ("translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % \ + (pat.tex_mov_x, pat.tex_mov_y, pat.tex_mov_z, + 1.0 / pat.tex_scale_x, 1.0 / pat.tex_scale_y, 1.0 / pat.tex_scale_z)) + texStrg="" + def exportColorRamp(texture): + tex=texture + pat = tex.pov + colRampStrg="color_map {\n" + numColor=0 + for el in tex.color_ramp.elements: + numColor+=1 + pos = el.position + col=el.color + colR,colG,colB,colA = col[0],col[1],col[2],1-col[3] + if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} : + colRampStrg+="[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n"%(pos,colR,colG,colB,colA) + if pat.tex_pattern_type in {'brick','checker'} and numColor < 3: + colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'hexagon' and numColor < 4 : + colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'square' and numColor < 5 : + colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'triangular' and numColor < 7 : + colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + + colRampStrg+="} \n" + #end color map + return colRampStrg + #much work to be done here only defaults translated for now: + #pov noise_generator 3 means perlin noise + if pat.tex_pattern_type == 'emulator': + texStrg+="pigment {\n" + ####################### EMULATE BLENDER VORONOI TEXTURE #################### + if tex.type == 'VORONOI': + texStrg+="crackle\n" + texStrg+=" offset %.4g\n"%tex.nabla + texStrg+=" form <%.4g,%.4g,%.4g>\n"%(tex.weight_1, tex.weight_2, tex.weight_3) + if tex.distance_metric == 'DISTANCE': + texStrg+=" metric 2.5\n" + if tex.distance_metric == 'DISTANCE_SQUARED': + texStrg+=" metric 2.5\n" + texStrg+=" poly_wave 2\n" + if tex.distance_metric == 'MINKOVSKY': + texStrg+=" metric %s\n"%tex.minkovsky_exponent + if tex.distance_metric == 'MINKOVSKY_FOUR': + texStrg+=" metric 4\n" + if tex.distance_metric == 'MINKOVSKY_HALF': + texStrg+=" metric 0.5\n" + if tex.distance_metric == 'CHEBYCHEV': + texStrg+=" metric 10\n" + if tex.distance_metric == 'MANHATTAN': + texStrg+=" metric 1\n" + + if tex.color_mode == 'POSITION': + texStrg+="solid\n" + texStrg+="scale 0.25\n" + + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<0,0,0,1>]\n" + texStrg+="[1 color rgbt<1,1,1,0>]\n" + texStrg+="}\n" + ####################### EMULATE BLENDER CLOUDS TEXTURE #################### + if tex.type == 'CLOUDS': + if tex.noise_type == 'SOFT_NOISE': + texStrg+="wrinkles\n" + texStrg+="scale 0.25\n" + else: + texStrg+="granite\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<0,0,0,1>]\n" + texStrg+="[1 color rgbt<1,1,1,0>]\n" + texStrg+="}\n" + ####################### EMULATE BLENDER WOOD TEXTURE #################### + if tex.type == 'WOOD': + if tex.wood_type == 'RINGS': + texStrg+="wood\n" + texStrg+="scale 0.25\n" + if tex.wood_type == 'RINGNOISE': + texStrg+="wood\n" + texStrg+="scale 0.25\n" + texStrg+="turbulence %.4g\n"%(tex.turbulence/100) + if tex.wood_type == 'BANDS': + texStrg+="marble\n" + texStrg+="scale 0.25\n" + texStrg+="rotate <45,-45,45>\n" + if tex.wood_type == 'BANDNOISE': + texStrg+="marble\n" + texStrg+="scale 0.25\n" + texStrg+="rotate <45,-45,45>\n" + texStrg+="turbulence %.4g\n"%(tex.turbulence/10) + + if tex.noise_basis_2 == 'SIN': + texStrg+="sine_wave\n" + if tex.noise_basis_2 == 'TRI': + texStrg+="triangle_wave\n" + if tex.noise_basis_2 == 'SAW': + texStrg+="ramp_wave\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<0,0,0,0>]\n" + texStrg+="[1 color rgbt<1,1,1,0>]\n" + texStrg+="}\n" + ####################### EMULATE BLENDER STUCCI TEXTURE #################### + if tex.type == 'STUCCI': + texStrg+="bozo\n" + texStrg+="scale 0.25\n" + if tex.noise_type == 'HARD_NOISE': + texStrg+="triangle_wave\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbf<1,1,1,0>]\n" + texStrg+="[1 color rgbt<0,0,0,1>]\n" + texStrg+="}\n" + else: + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbf<0,0,0,1>]\n" + texStrg+="[1 color rgbt<1,1,1,0>]\n" + texStrg+="}\n" + ####################### EMULATE BLENDER MAGIC TEXTURE #################### + if tex.type == 'MAGIC': + texStrg+="leopard\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0.5>]\n" + texStrg+="[0.25 color rgbf<0,1,0,0.75>]\n" + texStrg+="[0.5 color rgbf<0,0,1,0.75>]\n" + texStrg+="[0.75 color rgbf<1,0,1,0.75>]\n" + texStrg+="[1 color rgbf<0,1,0,0.75>]\n" + texStrg+="}\n" + texStrg+="scale 0.1\n" + ####################### EMULATE BLENDER MARBLE TEXTURE #################### + if tex.type == 'MARBLE': + texStrg+="marble\n" + texStrg+="turbulence 0.5\n" + texStrg+="noise_generator 3\n" + texStrg+="scale 0.75\n" + texStrg+="rotate <45,-45,45>\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + if tex.marble_type == 'SOFT': + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<0,0,0,0>]\n" + texStrg+="[0.05 color rgbt<0,0,0,0>]\n" + texStrg+="[1 color rgbt<0.9,0.9,0.9,0>]\n" + texStrg+="}\n" + elif tex.marble_type == 'SHARP': + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<0,0,0,0>]\n" + texStrg+="[0.025 color rgbt<0,0,0,0>]\n" + texStrg+="[1 color rgbt<0.9,0.9,0.9,0>]\n" + texStrg+="}\n" + else: + texStrg+="[0 color rgbt<0,0,0,0>]\n" + texStrg+="[1 color rgbt<1,1,1,0>]\n" + texStrg+="}\n" + if tex.noise_basis_2 == 'SIN': + texStrg+="sine_wave\n" + if tex.noise_basis_2 == 'TRI': + texStrg+="triangle_wave\n" + if tex.noise_basis_2 == 'SAW': + texStrg+="ramp_wave\n" + ####################### EMULATE BLENDER BLEND TEXTURE #################### + if tex.type == 'BLEND': + if tex.progression=='RADIAL': + texStrg+="radial\n" + if tex.use_flip_axis=='HORIZONTAL': + texStrg+="rotate x*90\n" + else: + texStrg+="rotate <-90,0,90>\n" + texStrg+="ramp_wave\n" + elif tex.progression=='SPHERICAL': + texStrg+="spherical\n" + texStrg+="scale 3\n" + texStrg+="poly_wave 1\n" + elif tex.progression=='QUADRATIC_SPHERE': + texStrg+="spherical\n" + texStrg+="scale 3\n" + texStrg+=" poly_wave 2\n" + elif tex.progression=='DIAGONAL': + texStrg+="gradient <1,1,0>\n" + texStrg+="scale 3\n" + elif tex.use_flip_axis=='HORIZONTAL': + texStrg+="gradient x\n" + texStrg+="scale 2.01\n" + elif tex.use_flip_axis=='VERTICAL': + texStrg+="gradient y\n" + texStrg+="scale 2.01\n" + #texStrg+="ramp_wave\n" + #texStrg+="frequency 0.5\n" + texStrg+="phase 0.5\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + if tex.progression == 'LINEAR': + texStrg+=" poly_wave 1\n" + if tex.progression == 'QUADRATIC': + texStrg+=" poly_wave 2\n" + if tex.progression == 'EASING': + texStrg+=" poly_wave 1.5\n" + ####################### EMULATE BLENDER MUSGRAVE TEXTURE #################### + # if tex.type == 'MUSGRAVE': + # texStrg+="function{ f_ridged_mf( x, y, 0, 1, 2, 9, -0.5, 3,3 )*0.5}\n" + # texStrg+="color_map {\n" + # texStrg+="[0 color rgbf<0,0,0,1>]\n" + # texStrg+="[1 color rgbf<1,1,1,0>]\n" + # texStrg+="}\n" + # simplified for now: + + if tex.type == 'MUSGRAVE': + texStrg+="bozo scale 0.25 \n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {[0.5 color rgbf<0,0,0,1>][1 color rgbt<1,1,1,0>]}ramp_wave \n" + ####################### EMULATE BLENDER DISTORTED NOISE TEXTURE #################### + if tex.type == 'DISTORTED_NOISE': + texStrg+="average\n" + texStrg+=" pigment_map {\n" + texStrg+=" [1 bozo scale 0.25 turbulence %.4g\n" %tex.distortion + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + texStrg+="]\n" + + if tex.noise_distortion == 'CELL_NOISE': + texStrg+=" [1 cells scale 0.1\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + texStrg+="]\n" + if tex.noise_distortion=='VORONOI_CRACKLE': + texStrg+=" [1 crackle scale 0.25\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + texStrg+="]\n" + if tex.noise_distortion in ['VORONOI_F1','VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1']: + texStrg+=" [1 crackle metric 2.5 scale 0.25 turbulence %.4g\n" %(tex.distortion/2) + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + texStrg+="]\n" + else: + texStrg+=" [1 wrinkles scale 0.25\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0 color rgbt<1,1,1,0>]\n" + texStrg+="[1 color rgbf<0,0,0,1>]\n" + texStrg+="}\n" + texStrg+="]\n" + texStrg+=" }\n" + ####################### EMULATE BLENDER NOISE TEXTURE #################### + if tex.type == 'NOISE': + texStrg+="cells\n" + texStrg+="turbulence 3\n" + texStrg+="omega 3\n" + if tex.use_color_ramp == True: + texStrg+=exportColorRamp(tex) + else: + texStrg+="color_map {\n" + texStrg+="[0.75 color rgb<0,0,0,>]\n" + texStrg+="[1 color rgb<1,1,1,>]\n" + texStrg+="}\n" + + ####################### IGNORE OTHER BLENDER TEXTURE #################### + else: #non translated textures + pass + texStrg+="}\n\n" + texStrg+="#declare f%s=\n"%PATname + texStrg+="function{pigment{%s}}\n"%PATname + texStrg+="\n" + + else: + texStrg+="pigment {\n" + texStrg+="%s\n"%pat.tex_pattern_type + if pat.tex_pattern_type == 'agate': + texStrg+="agate_turb %.4g\n"%pat.modifier_turbulence + if pat.tex_pattern_type in {'spiral1', 'spiral2', 'tiling'}: + texStrg+="%s\n"%pat.modifier_numbers + if pat.tex_pattern_type == 'quilted': + texStrg+="control0 %s control1 %s\n"%(pat.modifier_control0, pat.modifier_control1) + if pat.tex_pattern_type == 'mandel': + texStrg+="%s exponent %s \n"%(pat.f_iter, pat.f_exponent) + if pat.tex_pattern_type == 'julia': + texStrg+="<%.4g, %.4g> %s exponent %s \n"%(pat.julia_complex_1, pat.julia_complex_2, pat.f_iter, pat.f_exponent) + if pat.tex_pattern_type == 'magnet' and pat.magnet_style == 'mandel': + texStrg+="%s mandel %s \n"%(pat.magnet_type, pat.f_iter) + if pat.tex_pattern_type == 'magnet' and pat.magnet_style == 'julia': + texStrg+="%s julia <%.4g, %.4g> %s\n"%(pat.magnet_type, pat.julia_complex_1, pat.julia_complex_2, pat.f_iter) + if pat.tex_pattern_type in {'mandel', 'julia', 'magnet'}: + texStrg+="interior %s, %.4g\n"%(pat.f_ior, pat.f_ior_fac) + texStrg+="exterior %s, %.4g\n"%(pat.f_eor, pat.f_eor_fac) + if pat.tex_pattern_type == 'gradient': + texStrg+="<%s, %s, %s> \n"%(pat.grad_orient_x, pat.grad_orient_y, pat.grad_orient_z) + if pat.tex_pattern_type == 'pavement': + numTiles=pat.pave_tiles + numPattern=1 + if pat.pave_sides == '4' and pat.pave_tiles == 3: + numPattern = pat.pave_pat_2 + if pat.pave_sides == '6' and pat.pave_tiles == 3: + numPattern = pat.pave_pat_3 + if pat.pave_sides == '3' and pat.pave_tiles == 4: + numPattern = pat.pave_pat_3 + if pat.pave_sides == '3' and pat.pave_tiles == 5: + numPattern = pat.pave_pat_4 + if pat.pave_sides == '4' and pat.pave_tiles == 4: + numPattern = pat.pave_pat_5 + if pat.pave_sides == '6' and pat.pave_tiles == 4: + numPattern = pat.pave_pat_7 + if pat.pave_sides == '4' and pat.pave_tiles == 5: + numPattern = pat.pave_pat_12 + if pat.pave_sides == '3' and pat.pave_tiles == 6: + numPattern = pat.pave_pat_12 + if pat.pave_sides == '6' and pat.pave_tiles == 5: + numPattern = pat.pave_pat_22 + if pat.pave_sides == '4' and pat.pave_tiles == 6: + numPattern = pat.pave_pat_35 + if pat.pave_sides == '6' and pat.pave_tiles == 6: + numTiles = 5 + texStrg+="number_of_sides %s number_of_tiles %s pattern %s form %s \n"%(pat.pave_sides, numTiles, numPattern, pat.pave_form) + ################ functions ##################################################################################################### + if pat.tex_pattern_type == 'function': + texStrg+="{ %s"%pat.func_list + texStrg+="(x" + if pat.func_plus_x != "NONE": + if pat.func_plus_x =='increase': + texStrg+="*" + if pat.func_plus_x =='plus': + texStrg+="+" + texStrg+="%.4g"%pat.func_x + texStrg+=",y" + if pat.func_plus_y != "NONE": + if pat.func_plus_y =='increase': + texStrg+="*" + if pat.func_plus_y =='plus': + texStrg+="+" + texStrg+="%.4g"%pat.func_y + texStrg+=",z" + if pat.func_plus_z != "NONE": + if pat.func_plus_z =='increase': + texStrg+="*" + if pat.func_plus_z =='plus': + texStrg+="+" + texStrg+="%.4g"%pat.func_z + sort = -1 + if pat.func_list in {"f_comma","f_crossed_trough","f_cubic_saddle","f_cushion","f_devils_curve", + "f_enneper","f_glob","f_heart","f_hex_x","f_hex_y","f_hunt_surface", + "f_klein_bottle","f_kummer_surface_v1","f_lemniscate_of_gerono","f_mitre", + "f_nodal_cubic","f_noise_generator","f_odd","f_paraboloid","f_pillow", + "f_piriform","f_quantum","f_quartic_paraboloid","f_quartic_saddle", + "f_sphere","f_steiners_roman","f_torus_gumdrop","f_umbrella"}: + sort = 0 + if pat.func_list in {"f_bicorn","f_bifolia","f_boy_surface","f_superellipsoid","f_torus"}: + sort = 1 + if pat.func_list in {"f_ellipsoid","f_folium_surface","f_hyperbolic_torus", + "f_kampyle_of_eudoxus","f_parabolic_torus","f_quartic_cylinder","f_torus2"}: + sort = 2 + if pat.func_list in {"f_blob2","f_cross_ellipsoids","f_flange_cover","f_isect_ellipsoids", + "f_kummer_surface_v2","f_ovals_of_cassini","f_rounded_box","f_spikes_2d","f_strophoid"}: + sort = 3 + if pat.func_list in {"f_algbr_cyl1","f_algbr_cyl2","f_algbr_cyl3","f_algbr_cyl4","f_blob","f_mesh1","f_poly4","f_spikes"}: + sort = 4 + if pat.func_list in {"f_devils_curve_2d","f_dupin_cyclid","f_folium_surface_2d","f_hetero_mf","f_kampyle_of_eudoxus_2d", + "f_lemniscate_of_gerono_2d","f_polytubes","f_ridge","f_ridged_mf","f_spiral","f_witch_of_agnesi"}: + sort = 5 + if pat.func_list in {"f_helix1","f_helix2","f_piriform_2d","f_strophoid_2d"}: + sort = 6 + if pat.func_list == "f_helical_torus": + sort = 7 + if sort > -1: + texStrg+=",%.4g"%pat.func_P0 + if sort > 0: + texStrg+=",%.4g"%pat.func_P1 + if sort > 1: + texStrg+=",%.4g"%pat.func_P2 + if sort > 2: + texStrg+=",%.4g"%pat.func_P3 + if sort > 3: + texStrg+=",%.4g"%pat.func_P4 + if sort > 4: + texStrg+=",%.4g"%pat.func_P5 + if sort > 5: + texStrg+=",%.4g"%pat.func_P6 + if sort > 6: + texStrg+=",%.4g"%pat.func_P7 + texStrg+=",%.4g"%pat.func_P8 + texStrg+=",%.4g"%pat.func_P9 + texStrg+=")}\n" + ############## end functions ############################################################### + if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'}: + texStrg+="color_map {\n" + numColor=0 + if tex.use_color_ramp == True: + for el in tex.color_ramp.elements: + numColor+=1 + pos = el.position + col=el.color + colR,colG,colB,colA = col[0],col[1],col[2],1-col[3] + if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} : + texStrg+="[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n"%(pos,colR,colG,colB,colA) + if pat.tex_pattern_type in {'brick','checker'} and numColor < 3: + texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'hexagon' and numColor < 4 : + texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'square' and numColor < 5 : + texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + if pat.tex_pattern_type == 'triangular' and numColor < 7 : + texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA) + else: + texStrg+="[0 color rgbf<0,0,0,1>]\n" + texStrg+="[1 color rgbf<1,1,1,0>]\n" + if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} : + texStrg+="} \n" + if pat.tex_pattern_type == 'brick': + texStrg+="brick_size <%.4g, %.4g, %.4g> mortar %.4g \n"%(pat.brick_size_x, pat.brick_size_y, pat.brick_size_z, pat.brick_mortar) + texStrg+="%s \n"%mappingDif + texStrg+="rotate <%.4g,%.4g,%.4g> \n"%(pat.tex_rot_x, pat.tex_rot_y, pat.tex_rot_z) + texStrg+="turbulence <%.4g,%.4g,%.4g> \n"%(pat.warp_turbulence_x, pat.warp_turbulence_y, pat.warp_turbulence_z) + texStrg+="octaves %s \n"%pat.modifier_octaves + texStrg+="lambda %.4g \n"%pat.modifier_lambda + texStrg+="omega %.4g \n"%pat.modifier_omega + texStrg+="frequency %.4g \n"%pat.modifier_frequency + texStrg+="phase %.4g \n"%pat.modifier_phase + texStrg+="}\n\n" + texStrg+="#declare f%s=\n"%PATname + texStrg+="function{pigment{%s}}\n"%PATname + texStrg+="\n" + return(texStrg) def write_pov(filename, scene=None, info_callback=None): import mathutils @@ -167,6 +642,7 @@ def write_pov(filename, scene=None, info_callback=None): global_matrix = mathutils.Matrix.Rotation(-pi / 2.0, 4, 'X') comments = scene.pov.comments_enable and not scene.pov.tempfiles_enable linebreaksinlists= scene.pov.list_lf_enable and not scene.pov.tempfiles_enable + def setTab(tabtype, spaces): TabStr = "" if tabtype == 'NONE': @@ -301,7 +777,7 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") materialNames = {} - DEF_MAT_NAME = "Default" + DEF_MAT_NAME = "" #or "Default"? def writeMaterial(material): # Assumes only called once on each material @@ -509,7 +985,12 @@ def write_pov(filename, scene=None, info_callback=None): if material: special_texture_found = False for t in material.texture_slots: - if(t and t.texture.type == 'IMAGE' and t.use and t.texture.image and + if t and t.use: + if (t.texture.type == 'IMAGE' and t.texture.image) or t.texture.type != 'IMAGE': + validPath=True + else: + validPath=False + if(t and t.use and validPath and (t.use_map_specular or t.use_map_raymir or t.use_map_normal or t.use_map_alpha)): special_texture_found = True continue # Some texture found @@ -1337,7 +1818,7 @@ def write_pov(filename, scene=None, info_callback=None): vertCols[key] = [-1] idx = 0 - LocalMaterialNames = [] + LocalMaterialNames = [] for col, index in vertCols.items(): #if me_materials: mater = me_materials[col[3]] @@ -1351,7 +1832,7 @@ def write_pov(filename, scene=None, info_callback=None): trans = 1.0 - mater.alpha else: trans = 0.0 - if (mater.specular_color.r == mater.specular_color.g) and (mater.specular_color.r == mater.specular_color.b): + if (mater.specular_color.s == 0.0): colored_specular_found = False else: colored_specular_found = True @@ -1367,9 +1848,52 @@ def write_pov(filename, scene=None, info_callback=None): texturesSpec = "" texturesNorm = "" texturesAlpha = "" + #proceduralFlag=False for t in mater.texture_slots: - if t and t.texture.type == 'IMAGE' and t.use and t.texture.image: - image_filename = path_image(t.texture.image) + if t and t.use and t.texture.type != 'IMAGE' and t.texture.type != 'NONE': + proceduralFlag=True + image_filename = "PAT_%s"%string_strip_hyphen(bpy.path.clean_name(t.texture.name)) + if image_filename: + if t.use_map_color_diffuse: + texturesDif = image_filename + # colvalue = t.default_value # UNUSED + t_dif = t + if t_dif.texture.pov.tex_gamma_enable: + imgGamma = (" gamma %.3g " % t_dif.texture.pov.tex_gamma_value) + if t.use_map_specular or t.use_map_raymir: + texturesSpec = image_filename + # colvalue = t.default_value # UNUSED + t_spec = t + if t.use_map_normal: + texturesNorm = image_filename + # colvalue = t.normal_factor * 10.0 # UNUSED + #textNormName=t.texture.image.name + ".normal" + #was the above used? --MR + t_nor = t + if t.use_map_alpha: + texturesAlpha = image_filename + # colvalue = t.alpha_factor * 10.0 # UNUSED + #textDispName=t.texture.image.name + ".displ" + #was the above used? --MR + t_alpha = t + + if t and t.texture.type == 'IMAGE' and t.use and t.texture.image and t.texture.pov.tex_pattern_type == 'emulator': + proceduralFlag=False + if t.texture.image.packed_file: + orig_image_filename=t.texture.image.filepath_raw + workDir=os.path.dirname(__file__) + previewDir=os.path.join(workDir, "preview") + unpackedfilename= os.path.join(previewDir,("unpacked_img_"+(string_strip_hyphen(bpy.path.clean_name(t.texture.name))))) + if not os.path.exists(unpackedfilename): + # record which images that were newly copied and can be safely + # cleaned up + unpacked_images.append(unpackedfilename) + t.texture.image.filepath_raw=unpackedfilename + t.texture.image.save() + image_filename = unpackedfilename + t.texture.image.filepath_raw=orig_image_filename + else: + image_filename = path_image(t.texture.image) # IMAGE SEQUENCE BEGINS if image_filename: if bpy.data.images[t.texture.image.name].source == 'SEQUENCE': @@ -1452,17 +1976,20 @@ def write_pov(filename, scene=None, info_callback=None): if texturesSpec != "": # tabWrite("\n") tabWrite("pigment_pattern {\n") - # POV-Ray "scale" is not a number of repetitions factor, but its - # inverse, a standard scale factor. - # Offset seems needed relatively to scale so probably center of the - # scale is not the same in blender and POV - mappingSpec = "translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>\n" % \ - (-t_spec.offset.x, t_spec.offset.y, t_spec.offset.z, - 1.0 / t_spec.scale.x, 1.0 / t_spec.scale.y, - 1.0 / t_spec.scale.z) - tabWrite("uv_mapping image_map{%s \"%s\" %s}\n" % \ - (imageFormat(texturesSpec), texturesSpec, imgMap(t_spec))) - tabWrite("%s\n" % mappingSpec) + if texturesSpec and texturesSpec.startswith("PAT_"): + tabWrite("function{f%s(x,y,z).grey}" %texturesSpec) + else: + # POV-Ray "scale" is not a number of repetitions factor, but its + # inverse, a standard scale factor. + # Offset seems needed relatively to scale so probably center of the + # scale is not the same in blender and POV + mappingSpec = "translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>\n" % \ + (-t_spec.offset.x, t_spec.offset.y, t_spec.offset.z, + 1.0 / t_spec.scale.x, 1.0 / t_spec.scale.y, + 1.0 / t_spec.scale.z) + tabWrite("uv_mapping image_map{%s \"%s\" %s}\n" % \ + (imageFormat(texturesSpec), texturesSpec, imgMap(t_spec))) + tabWrite("%s\n" % mappingSpec) tabWrite("}\n") tabWrite("texture_map {\n") tabWrite("[0 \n") @@ -1470,19 +1997,22 @@ def write_pov(filename, scene=None, info_callback=None): if texturesDif == "": if texturesAlpha != "": tabWrite("\n") - # POV-Ray "scale" is not a number of repetitions factor, but its - # inverse, a standard scale factor. - # Offset seems needed relatively to scale so probably center of the - # scale is not the same in blender and POV - mappingAlpha = " translate <%.4g, %.4g, %.4g> " \ - "scale <%.4g, %.4g, %.4g>\n" % \ - (-t_alpha.offset.x, -t_alpha.offset.y, - t_alpha.offset.z, 1.0 / t_alpha.scale.x, - 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z) - tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ - "{%s \"%s\" %s}%s" % \ - (imageFormat(texturesAlpha), texturesAlpha, - imgMap(t_alpha), mappingAlpha)) + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("function{f%s(x,y,z).transmit}\n" %texturesAlpha) + else: + # POV-Ray "scale" is not a number of repetitions factor, but its + # inverse, a standard scale factor. + # Offset seems needed relatively to scale so probably center of the + # scale is not the same in blender and POV + mappingAlpha = " translate <%.4g, %.4g, %.4g> " \ + "scale <%.4g, %.4g, %.4g>\n" % \ + (-t_alpha.offset.x, -t_alpha.offset.y, + t_alpha.offset.z, 1.0 / t_alpha.scale.x, + 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z) + tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ + "{%s \"%s\" %s}%s" % \ + (imageFormat(texturesAlpha), texturesAlpha, + imgMap(t_alpha), mappingAlpha)) tabWrite("}\n") tabWrite("pigment_map {\n") tabWrite("[0 color rgbft<0,0,0,1,1>]\n") @@ -1525,21 +2055,34 @@ def write_pov(filename, scene=None, info_callback=None): 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z) tabWrite("pigment {\n") tabWrite("pigment_pattern {\n") - tabWrite("uv_mapping image_map{%s \"%s\" %s}%s}\n" % \ - (imageFormat(texturesAlpha), texturesAlpha, - imgMap(t_alpha), mappingAlpha)) + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("function{f%s(x,y,z).transmit}\n" %texturesAlpha) + else: + tabWrite("uv_mapping image_map{%s \"%s\" %s}%s}\n" % \ + (imageFormat(texturesAlpha), texturesAlpha, + imgMap(t_alpha), mappingAlpha)) tabWrite("pigment_map {\n") tabWrite("[0 color rgbft<0,0,0,1,1>]\n") - tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \ - (imageFormat(texturesDif), texturesDif, - (imgGamma + imgMap(t_dif)), mappingDif)) + #if texturesAlpha and texturesAlpha.startswith("PAT_"): + #tabWrite("[1 pigment{%s}]\n" %texturesDif) + if texturesDif and not texturesDif.startswith("PAT_"): + tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \ + (imageFormat(texturesDif), texturesDif, + (imgGamma + imgMap(t_dif)), mappingDif)) + elif texturesDif and texturesDif.startswith("PAT_"): + tabWrite("[1 %s]\n" %texturesDif) tabWrite("}\n") tabWrite("}\n") + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("}\n") else: - tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s}\n" % \ - (imageFormat(texturesDif), texturesDif, - (imgGamma + imgMap(t_dif)), mappingDif)) + if texturesDif and texturesDif.startswith("PAT_"): + tabWrite("pigment{%s}\n" %texturesDif) + else: + tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s}\n" % \ + (imageFormat(texturesDif), texturesDif, + (imgGamma + imgMap(t_dif)), mappingDif)) if texturesSpec != "": # Level 1 is no specular @@ -1571,10 +2114,13 @@ def write_pov(filename, scene=None, info_callback=None): #imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % \ # (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor))) #We were not using the above maybe we should? - tabWrite("normal {uv_mapping bump_map " \ - "{%s \"%s\" %s bump_size %.4g }%s}\n" % \ - (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), - t_nor.normal_factor * 10, mappingNor)) + if texturesNorm and texturesNorm.startswith("PAT_"): + tabWrite("normal{function{f%s(x,y,z).grey} bump_size %.4g}\n" %(texturesNorm, t_nor.normal_factor * 10)) + else: + tabWrite("normal {uv_mapping bump_map " \ + "{%s \"%s\" %s bump_size %.4g }%s}\n" % \ + (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), + t_nor.normal_factor * 10, mappingNor)) if texturesSpec != "": tabWrite("]\n") ##################Second index for mapping specular max value############### @@ -1593,10 +2139,13 @@ def write_pov(filename, scene=None, info_callback=None): (-t_alpha.offset.x, -t_alpha.offset.y, t_alpha.offset.z, 1.0 / t_alpha.scale.x, 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z) - tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ - "{%s \"%s\" %s}%s}\n" % \ - (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), - mappingAlpha)) + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("function{f%s(x,y,z).transmit}\n" %texturesAlpha) + else: + tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ + "{%s \"%s\" %s}%s}\n" % \ + (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), + mappingAlpha)) tabWrite("pigment_map {\n") tabWrite("[0 color rgbft<0,0,0,1,1>]\n") tabWrite("[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n" % \ @@ -1640,29 +2189,40 @@ def write_pov(filename, scene=None, info_callback=None): (-t_alpha.offset.x, -t_alpha.offset.y, t_alpha.offset.z, 1.0 / t_alpha.scale.x, 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z) - tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ - "{%s \"%s\" %s}%s}\n" % \ - (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), - mappingAlpha)) + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("pigment{pigment_pattern {function{f%s(x,y,z).transmit}}\n" %texturesAlpha) + else: + tabWrite("pigment {pigment_pattern {uv_mapping image_map" \ + "{%s \"%s\" %s}%s}\n" % \ + (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), + mappingAlpha)) tabWrite("pigment_map {\n") tabWrite("[0 color rgbft<0,0,0,1,1>]\n") - tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \ - (imageFormat(texturesDif), texturesDif, - (imgMap(t_dif) + imgGamma), mappingDif)) + if texturesAlpha and texturesAlpha.startswith("PAT_"): + tabWrite("[1 function{f%s(x,y,z).transmit}]\n" %texturesAlpha) + elif texturesDif and not texturesDif.startswith("PAT_"): + tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \ + (imageFormat(texturesDif), texturesDif, + (imgMap(t_dif) + imgGamma), mappingDif)) + elif texturesDif and texturesDif.startswith("PAT_"): + tabWrite("[1 %s]\n" %texturesDif) tabWrite("}\n") tabWrite("}\n") else: - tabWrite("pigment {\n") - tabWrite("uv_mapping image_map {\n") - #tabWrite("%s \"%s\" %s}%s\n" % \ - # (imageFormat(texturesDif), texturesDif, - # (imgGamma + imgMap(t_dif)),mappingDif)) - tabWrite("%s \"%s\" \n" % (imageFormat(texturesDif), texturesDif)) - tabWrite("%s\n" % (imgGamma + imgMap(t_dif))) - tabWrite("}\n") - tabWrite("%s\n" % mappingDif) - tabWrite("}\n") + if texturesDif and texturesDif.startswith("PAT_"): + tabWrite("pigment{%s}\n" %texturesDif) + else: + tabWrite("pigment {\n") + tabWrite("uv_mapping image_map {\n") + #tabWrite("%s \"%s\" %s}%s\n" % \ + # (imageFormat(texturesDif), texturesDif, + # (imgGamma + imgMap(t_dif)),mappingDif)) + tabWrite("%s \"%s\" \n" % (imageFormat(texturesDif), texturesDif)) + tabWrite("%s\n" % (imgGamma + imgMap(t_dif))) + tabWrite("}\n") + tabWrite("%s\n" % mappingDif) + tabWrite("}\n") if texturesSpec != "": # Level 3 is full specular @@ -1692,9 +2252,12 @@ def write_pov(filename, scene=None, info_callback=None): #imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % \ # (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor))) #We were not using the above maybe we should? - tabWrite("normal {uv_mapping bump_map {%s \"%s\" %s bump_size %.4g }%s}\n" % \ - (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), - t_nor.normal_factor * 10.0, mappingNor)) + if texturesNorm and texturesNorm.startswith("PAT_"): + tabWrite("normal{function{f%s(x,y,z).grey} bump_size %.4g}\n" %(texturesNorm, t_nor.normal_factor * 10)) + else: + tabWrite("normal {uv_mapping bump_map {%s \"%s\" %s bump_size %.4g }%s}\n" % \ + (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), + t_nor.normal_factor * 10.0, mappingNor)) if texturesSpec != "" and mater.pov.replacement_text == "": tabWrite("]\n") @@ -1725,7 +2288,7 @@ def write_pov(filename, scene=None, info_callback=None): # to emulate colored specular highlights special_texture_found = False for t in mater.texture_slots: - if(t and t.texture.type == 'IMAGE' and t.use and t.texture.image and + if(t and t.use and ((t.texture.type == 'IMAGE' and t.texture.image) or t.texture.type != 'IMAGE') and (t.use_map_specular or t.use_map_raymir)): # Specular mapped textures would conflict with colored specular # because POV can't layer over or under pigment patterned textures @@ -1733,7 +2296,7 @@ def write_pov(filename, scene=None, info_callback=None): if colored_specular_found and not special_texture_found: if comments: - file.write(" //Emulating colored highlights with a metallic layer\n") + file.write(" // colored highlights with a stransparent metallic layer\n") else: tabWrite("\n") @@ -1744,7 +2307,12 @@ def write_pov(filename, scene=None, info_callback=None): texturesNorm = "" for t in mater.texture_slots: - if t and t.texture.type == 'IMAGE' and t.use and t.texture.image: + + if t and t.texture.pov.tex_pattern_type != 'emulator': + proceduralFlag=True + image_filename = string_strip_hyphen(bpy.path.clean_name(t.texture.name)) + if t and t.texture.type == 'IMAGE' and t.use and t.texture.image and t.texture.pov.tex_pattern_type == 'emulator': + proceduralFlag=False image_filename = path_image(t.texture.image) imgGamma = "" if image_filename: @@ -1754,12 +2322,14 @@ def write_pov(filename, scene=None, info_callback=None): #textNormName=t.texture.image.name + ".normal" #was the above used? --MR t_nor = t - - tabWrite("normal {uv_mapping bump_map " \ - "{%s \"%s\" %s bump_size %.4g }%s}\n" % \ - (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), - t_nor.normal_factor * 10, mappingNor)) - + if proceduralFlag: + tabWrite("normal{function{f%s(x,y,z).grey} bump_size %.4g}\n" %(texturesNorm, t_nor.normal_factor * 10)) + else: + tabWrite("normal {uv_mapping bump_map " \ + "{%s \"%s\" %s bump_size %.4g }%s}\n" % \ + (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), + t_nor.normal_factor * 10, mappingNor)) + tabWrite("}\n") # THEN IT CAN CLOSE LAST LAYER OF TEXTURE --MR @@ -1772,18 +2342,23 @@ def write_pov(filename, scene=None, info_callback=None): # Vert Colors tabWrite("texture_list {\n") - file.write(tabStr + "%s" % (len(vertCols))) # vert count - - if mater.pov.replacement_text != "": - file.write("\n") - file.write(" texture{%s}\n" % material.pov.replacement_text) + # In case there's is no material slot, give at least one texture (empty so it uses pov default) + if len(vertCols)==0: + file.write(tabStr + "1") + else: + file.write(tabStr + "%s" % (len(vertCols))) # vert count + if me_materials: + if mater.pov.replacement_text != "": + file.write("\n") + file.write(" texture{%s}\n" % material.pov.replacement_text) + else: + # Loop through declared materials list + for cMN in LocalMaterialNames: + if material != "Default": + file.write("\n texture{MAT_%s}\n" % cMN)#string_strip_hyphen(materialNames[material])) # Something like that else: - # Loop through declared materials list - for cMN in LocalMaterialNames: - if material != "Default": - file.write("\n texture{MAT_%s}\n" % cMN)#string_strip_hyphen(materialNames[material])) # Something like that - + file.write(" texture{}\n") tabWrite("}\n") # Face indices @@ -2148,7 +2723,7 @@ def write_pov(filename, scene=None, info_callback=None): file.write(txt.as_string()) file.write("\n") - sel = renderable_objects(scene) + sel = renderable_objects() if comments: file.write("//----------------------------------------------\n" \ "//--Exported with POV-Ray exporter for Blender--\n" \ @@ -2164,7 +2739,17 @@ def write_pov(filename, scene=None, info_callback=None): if comments: file.write("\n//--Custom Code--\n\n") exportCustomCode() - + + if comments: + file.write("\n//--Patterns Definitions--\n\n") + LocalPatternNames = [] + for texture in bpy.data.textures: #ok? + if texture.users > 0: + currentPatName = string_strip_hyphen(bpy.path.clean_name(texture.name)) #string_strip_hyphen(patternNames[texture.name]) #maybe instead + LocalPatternNames.append(currentPatName) #use this list to prevent writing texture instances several times and assign in mats? + file.write("\n #declare PAT_%s = \n" % currentPatName) + file.write(exportPattern(texture)) + file.write("\n") if comments: file.write("\n//--Background--\n\n") @@ -2182,7 +2767,8 @@ def write_pov(filename, scene=None, info_callback=None): if comments: file.write("\n//--Material Definitions--\n\n") - + # write a default pigment for objects with no material (comment out to show black) + file.write("#default{ pigment{ color rgb 0.8 }}\n") # Convert all materials to strings we can access directly per vertex. #exportMaterials() writeMaterial(None) # default material @@ -2369,7 +2955,8 @@ class PovrayRender(bpy.types.RenderEngine): self._is_windows = False if sys.platform[:3] == "win": self._is_windows = True - #extra_args.append("/EXIT") + if"/EXIT" not in extra_args and not scene.pov.pov_editor: + extra_args.append("/EXIT") else: # added -d option to prevent render window popup which leads to segfault on linux extra_args.append("-d") @@ -2403,7 +2990,15 @@ class PovrayRender(bpy.types.RenderEngine): # Wait a bit before retrying file might be still in use by Blender, # and Windows does not know how to delete a file in use! time.sleep(self.DELAY) - + for i in unpacked_images: + for c in range(5): + try: + os.unlink(i) + break + except OSError: + # Wait a bit before retrying file might be still in use by Blender, + # and Windows does not know how to delete a file in use! + time.sleep(self.DELAY) def render(self, scene): import tempfile @@ -2669,3 +3264,93 @@ class PovrayRender(bpy.types.RenderEngine): if scene.pov.tempfiles_enable or scene.pov.deletefiles_enable: self._cleanup() + + + +#################################Operators######################################### +class RenderPovTexturePreview(Operator): + bl_idname = "tex.preview_update" + bl_label = "Update preview" + def execute(self, context): + tex=bpy.context.object.active_material.active_texture #context.texture + texPrevName=string_strip_hyphen(bpy.path.clean_name(tex.name))+"_prev" + workDir=os.path.dirname(__file__) + previewDir=os.path.join(workDir, "preview") + iniPrevFile=os.path.join(previewDir, "Preview.ini") + inputPrevFile=os.path.join(previewDir, "Preview.pov") + outputPrevFile=os.path.join(previewDir, texPrevName) + ##################### ini ########################################## + fileIni=open("%s"%iniPrevFile,"w") + fileIni.write('Version=3.7\n') + fileIni.write('Input_File_Name="%s"\n'%inputPrevFile) + fileIni.write('Output_File_Name="%s.png"\n'%outputPrevFile) + fileIni.write('Library_Path="%s"\n'%previewDir) + fileIni.write('Width=256\n') + fileIni.write('Height=256\n') + fileIni.write('Pause_When_Done=0\n') + fileIni.write('Output_File_Type=N\n') + fileIni.write('Output_Alpha=1\n') + fileIni.write('Antialias=on\n') + fileIni.write('Sampling_Method=2\n') + fileIni.write('Antialias_Depth=3\n') + fileIni.write('-d\n') + fileIni.close() + ##################### pov ########################################## + filePov=open("%s"%inputPrevFile,"w") + PATname = "PAT_"+string_strip_hyphen(bpy.path.clean_name(tex.name)) + filePov.write("#declare %s = \n"%PATname) + filePov.write(exportPattern(tex)) + + filePov.write("#declare Plane =\n") + filePov.write("mesh {\n") + filePov.write(" triangle {<-2.021,-1.744,2.021>,<-2.021,-1.744,-2.021>,<2.021,-1.744,2.021>}\n") + filePov.write(" triangle {<-2.021,-1.744,-2.021>,<2.021,-1.744,-2.021>,<2.021,-1.744,2.021>}\n") + filePov.write(" texture{%s}\n"%PATname) + filePov.write("}\n") + filePov.write("object {Plane}\n") + filePov.write("light_source {\n") + filePov.write(" <0,4.38,-1.92e-07>\n") + filePov.write(" color rgb<4, 4, 4>\n") + filePov.write(" parallel\n") + filePov.write(" point_at <0, 0, -1>\n") + filePov.write("}\n") + filePov.write("camera {\n") + filePov.write(" location <0, 0, 0>\n") + filePov.write(" look_at <0, 0, -1>\n") + filePov.write(" right <-1.0, 0, 0>\n") + filePov.write(" up <0, 1, 0>\n") + filePov.write(" angle 96.805211\n") + filePov.write(" rotate <-90.000003, -0.000000, 0.000000>\n") + filePov.write(" translate <0.000000, 0.000000, 0.000000>\n") + filePov.write("}\n") + filePov.close() + ##################### end write ########################################## + + pov_binary = PovrayRender._locate_binary() + + if sys.platform[:3] == "win": + p1=subprocess.Popen(["%s"%pov_binary,"/EXIT","%s"%iniPrevFile],stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + else: + p1=subprocess.Popen(["%s"%pov_binary,"-d","%s"%iniPrevFile],stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + p1.wait() + + tex.use_nodes = True + tree = tex.node_tree + links = tree.links + for n in tree.nodes: + tree.nodes.remove(n) + im = tree.nodes.new("TextureNodeImage") + pathPrev="%s.png"%outputPrevFile + im.image = bpy.data.images.load(pathPrev) + name=pathPrev + name=name.split("/") + name=name[len(name)-1] + im.name = name + im.location = 200,200 + previewer = tree.nodes.new('TextureNodeOutput') + previewer.label = "Preview" + previewer.location = 400,400 + links.new(im.outputs[0],previewer.inputs[0]) + #tex.type="IMAGE" # makes clip extend possible + #tex.extension="CLIP" + return {'FINISHED'} \ No newline at end of file diff --git a/render_povray/ui.py b/render_povray/ui.py index 7334909c4..59d3b5c24 100644 --- a/render_povray/ui.py +++ b/render_povray/ui.py @@ -57,6 +57,7 @@ for member in dir(properties_data_mesh): del properties_data_mesh from bl_ui import properties_texture +from bl_ui.properties_texture import context_tex_datablock for member in dir(properties_texture): subclass = getattr(properties_texture, member) try: @@ -65,6 +66,7 @@ for member in dir(properties_texture): pass del properties_texture + from bl_ui import properties_data_camera for member in dir(properties_data_camera): subclass = getattr(properties_data_camera, member) @@ -130,6 +132,14 @@ class TextureButtonsPanel(): rd = context.scene.render return tex and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES) +# class TextureTypePanel(TextureButtonsPanel): + + # @classmethod + # def poll(cls, context): + # tex = context.texture + # engine = context.scene.render.engine + # return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES)) + class ObjectButtonsPanel(): bl_space_type = 'PROPERTIES' @@ -156,11 +166,22 @@ class CameraDataButtonsPanel(): rd = context.scene.render return cam and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES) +class WorldButtonsPanel(): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "world" + # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here + @classmethod + def poll(cls, context): + wld = context.world + rd = context.scene.render + return wld and (rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES) + class TextButtonsPanel(): bl_space_type = 'TEXT_EDITOR' bl_region_type = 'UI' - bl_label = "P.O.V-Ray" + bl_label = "POV-Ray" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here @classmethod @@ -174,6 +195,8 @@ class RENDER_PT_povray_export_settings(RenderButtonsPanel, bpy.types.Panel): bl_label = "Export Settings" COMPAT_ENGINES = {'POVRAY_RENDER'} + def draw_header(self, context): + self.layout.label(icon='CONSOLE') def draw(self, context): layout = self.layout @@ -187,6 +210,7 @@ class RENDER_PT_povray_export_settings(RenderButtonsPanel, bpy.types.Panel): col.prop(scene.pov, "command_line_switches", text="") split = layout.split() split.prop(scene.pov, "tempfiles_enable", text="OS Tempfiles") + split.prop(scene.pov, "pov_editor", text="POV Editor") if not scene.pov.tempfiles_enable: split.prop(scene.pov, "deletefiles_enable", text="Delete files") @@ -209,13 +233,15 @@ class RENDER_PT_povray_export_settings(RenderButtonsPanel, bpy.types.Panel): class RENDER_PT_povray_render_settings(RenderButtonsPanel, bpy.types.Panel): bl_label = "Render Settings" + bl_icon = 'SETTINGS' COMPAT_ENGINES = {'POVRAY_RENDER'} + def draw_header(self, context): + self.layout.label(icon='SETTINGS') def draw(self, context): layout = self.layout scene = context.scene - layout.active = (scene.pov.max_trace_level != 0) col = layout.column() @@ -243,8 +269,10 @@ class RENDER_PT_povray_antialias(RenderButtonsPanel, bpy.types.Panel): def draw_header(self, context): scene = context.scene - - self.layout.prop(scene.pov, "antialias_enable", text="") + if scene.pov.antialias_enable: + self.layout.prop(scene.pov, "antialias_enable", text="", icon='ANTIALIASED') + else: + self.layout.prop(scene.pov, "antialias_enable", text="", icon='ALIASED') def draw(self, context): layout = self.layout @@ -275,11 +303,12 @@ class RENDER_PT_povray_antialias(RenderButtonsPanel, bpy.types.Panel): class RENDER_PT_povray_radiosity(RenderButtonsPanel, bpy.types.Panel): bl_label = "Radiosity" COMPAT_ENGINES = {'POVRAY_RENDER'} - def draw_header(self, context): scene = context.scene - - self.layout.prop(scene.pov, "radio_enable", text="") + if scene.pov.radio_enable: + self.layout.prop(scene.pov, "radio_enable", text="", icon='RADIO') + else: + self.layout.prop(scene.pov, "radio_enable", text="", icon='RADIOBUT_OFF') def draw(self, context): layout = self.layout @@ -323,7 +352,7 @@ class RENDER_PT_povray_radiosity(RenderButtonsPanel, bpy.types.Panel): split.prop(scene.pov, "radio_always_sample") -class RENDER_PT_povray_media(RenderButtonsPanel, bpy.types.Panel): +class RENDER_PT_povray_media(WorldButtonsPanel, bpy.types.Panel): bl_label = "Atmosphere Media" COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -500,7 +529,251 @@ class MATERIAL_PT_povray_replacement_text(MaterialButtonsPanel, bpy.types.Panel) col.label(text="Replace properties with:") col.prop(mat.pov, "replacement_text", text="") +class TEXTURE_PT_povray_type(TextureButtonsPanel, bpy.types.Panel): + bl_label = "POV-ray Textures" + COMPAT_ENGINES = {'POVRAY_RENDER'} + bl_options = {'HIDE_HEADER'} + + def draw(self, context): + layout = self.layout + + tex = context.texture + + split = layout.split(percentage=0.2) + split.label(text="POV:") + split.prop(tex.pov, "tex_pattern_type", text="") +class TEXTURE_PT_povray_preview(TextureButtonsPanel, bpy.types.Panel): + bl_label = "Preview" + COMPAT_ENGINES = {'POVRAY_RENDER'} + bl_options = {'HIDE_HEADER'} + + @classmethod + def poll(cls, context): + engine = context.scene.render.engine + if not hasattr(context, "texture_slot"): + return False + tex=context.texture + mat=context.material + return (tex and (tex.pov.tex_pattern_type != 'emulator') and (engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + tex = context.texture + slot = getattr(context, "texture_slot", None) + idblock = context_tex_datablock(context) + layout = self.layout + # if idblock: + # layout.template_preview(tex, parent=idblock, slot=slot) + if tex.pov.tex_pattern_type != 'emulator': + layout.operator("tex.preview_update") + else: + layout.template_preview(tex, slot=slot) + + +class TEXTURE_PT_povray_parameters(TextureButtonsPanel, bpy.types.Panel): + bl_label = "POV-ray Pattern Options" + COMPAT_ENGINES = {'POVRAY_RENDER'} + def draw(self, context): + mat = context.material + layout = self.layout + tex = context.texture + align=True + if tex is not None and tex.pov.tex_pattern_type != 'emulator': + if tex.pov.tex_pattern_type == 'agate': + layout.prop(tex.pov, "modifier_turbulence", text="Agate Turbulence") + if tex.pov.tex_pattern_type in {'spiral1', 'spiral2'}: + layout.prop(tex.pov, "modifier_numbers", text="Number of arms") + if tex.pov.tex_pattern_type == 'tiling': + layout.prop(tex.pov, "modifier_numbers", text="Pattern number") + if tex.pov.tex_pattern_type == 'magnet': + layout.prop(tex.pov, "magnet_style", text="Magnet style") + if tex.pov.tex_pattern_type == 'quilted': + row = layout.row(align=align) + row.prop(tex.pov, "modifier_control0", text="Control0") + row.prop(tex.pov, "modifier_control1", text="Control1") + if tex.pov.tex_pattern_type == 'brick': + col = layout.column(align=align) + row = col.row() + row.prop(tex.pov, "brick_size_x", text="Brick size X") + row.prop(tex.pov, "brick_size_y", text="Brick size Y") + row=col.row() + row.prop(tex.pov, "brick_size_z", text="Brick size Z") + row.prop(tex.pov, "brick_mortar", text="Brick mortar") + if tex.pov.tex_pattern_type in {'julia','mandel','magnet'}: + col = layout.column(align=align) + if tex.pov.tex_pattern_type == 'julia': + row = col.row() + row.prop(tex.pov, "julia_complex_1", text="Complex 1") + row.prop(tex.pov, "julia_complex_2", text="Complex 2") + if tex.pov.tex_pattern_type == 'magnet' and tex.pov.magnet_style == 'julia': + row = col.row() + row.prop(tex.pov, "julia_complex_1", text="Complex 1") + row.prop(tex.pov, "julia_complex_2", text="Complex 2") + row=col.row() + if tex.pov.tex_pattern_type in {'julia','mandel'}: + row.prop(tex.pov, "f_exponent", text="Exponent") + if tex.pov.tex_pattern_type == 'magnet': + row.prop(tex.pov, "magnet_type", text="Type") + row.prop(tex.pov, "f_iter", text="Iterations") + row=col.row() + row.prop(tex.pov, "f_ior", text="Interior") + row.prop(tex.pov, "f_ior_fac", text="Factor I") + row=col.row() + row.prop(tex.pov, "f_eor", text="Exterior") + row.prop(tex.pov, "f_eor_fac", text="Factor E") + if tex.pov.tex_pattern_type == 'gradient': + layout.label(text="Gradient orientation:") + column_flow = layout.column_flow(columns=3, align=True) + column_flow.prop(tex.pov, "grad_orient_x", text="X") + column_flow.prop(tex.pov, "grad_orient_y", text="Y") + column_flow.prop(tex.pov, "grad_orient_z", text="Z") + if tex.pov.tex_pattern_type == 'pavement': + layout.prop(tex.pov, "pave_sides", text="Pavement:number of sides") + col = layout.column(align=align) + column_flow = col.column_flow(columns=3, align=True) + column_flow.prop(tex.pov, "pave_tiles", text="Tiles") + if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 6: + column_flow.prop(tex.pov, "pave_pat_35", text="Pattern") + if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 5: + column_flow.prop(tex.pov, "pave_pat_22", text="Pattern") + if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 5: + column_flow.prop(tex.pov, "pave_pat_12", text="Pattern") + if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 6: + column_flow.prop(tex.pov, "pave_pat_12", text="Pattern") + if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 4: + column_flow.prop(tex.pov, "pave_pat_7", text="Pattern") + if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 4: + column_flow.prop(tex.pov, "pave_pat_5", text="Pattern") + if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 5: + column_flow.prop(tex.pov, "pave_pat_4", text="Pattern") + if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 3: + column_flow.prop(tex.pov, "pave_pat_3", text="Pattern") + if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 4: + column_flow.prop(tex.pov, "pave_pat_3", text="Pattern") + if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 3: + column_flow.prop(tex.pov, "pave_pat_2", text="Pattern") + if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 6: + column_flow.label(text="!!! 5 tiles!") + column_flow.prop(tex.pov, "pave_form", text="Form") + if tex.pov.tex_pattern_type == 'function': + layout.prop(tex.pov, "func_list", text="Functions") + if tex.pov.tex_pattern_type == 'function' and tex.pov.func_list != "NONE": + func = None + if tex.pov.func_list in {"f_noise3d", "f_ph", "f_r", "f_th"}: + func = 0 + if tex.pov.func_list in {"f_comma","f_crossed_trough","f_cubic_saddle", + "f_cushion","f_devils_curve","f_enneper","f_glob", + "f_heart","f_hex_x","f_hex_y","f_hunt_surface", + "f_klein_bottle","f_kummer_surface_v1", + "f_lemniscate_of_gerono","f_mitre","f_nodal_cubic", + "f_noise_generator","f_odd","f_paraboloid","f_pillow", + "f_piriform","f_quantum","f_quartic_paraboloid", + "f_quartic_saddle","f_sphere","f_steiners_roman", + "f_torus_gumdrop","f_umbrella"}: + func = 1 + if tex.pov.func_list in {"f_bicorn","f_bifolia","f_boy_surface","f_superellipsoid","f_torus"}: + func = 2 + if tex.pov.func_list in {"f_ellipsoid","f_folium_surface","f_hyperbolic_torus", + "f_kampyle_of_eudoxus","f_parabolic_torus", + "f_quartic_cylinder","f_torus2"}: + func = 3 + if tex.pov.func_list in {"f_blob2","f_cross_ellipsoids","f_flange_cover", + "f_isect_ellipsoids","f_kummer_surface_v2","f_ovals_of_cassini", + "f_rounded_box","f_spikes_2d","f_strophoid"}: + func = 4 + if tex.pov.func_list in {"f_algbr_cyl1","f_algbr_cyl2","f_algbr_cyl3","f_algbr_cyl4", + "f_blob","f_mesh1","f_poly4","f_spikes"}: + func = 5 + if tex.pov.func_list in {"f_devils_curve_2d","f_dupin_cyclid","f_folium_surface_2d", + "f_hetero_mf","f_kampyle_of_eudoxus_2d","f_lemniscate_of_gerono_2d", + "f_polytubes","f_ridge","f_ridged_mf","f_spiral","f_witch_of_agnesi"}: + func = 6 + if tex.pov.func_list in {"f_helix1","f_helix2","f_piriform_2d","f_strophoid_2d"}: + func = 7 + if tex.pov.func_list == "f_helical_torus": + func = 8 + column_flow = layout.column_flow(columns=3, align=True) + column_flow.label(text="X") + column_flow.prop(tex.pov, "func_plus_x", text="") + column_flow.prop(tex.pov, "func_x", text="Value") + column_flow = layout.column_flow(columns=3, align=True) + column_flow.label(text="Y") + column_flow.prop(tex.pov, "func_plus_y", text="") + column_flow.prop(tex.pov, "func_y", text="Value") + column_flow = layout.column_flow(columns=3, align=True) + column_flow.label(text="Z") + column_flow.prop(tex.pov, "func_plus_z", text="") + column_flow.prop(tex.pov, "func_z", text="Value") + row=layout.row(align=align) + if func > 0: + row.prop(tex.pov, "func_P0", text="P0") + if func > 1: + row.prop(tex.pov, "func_P1", text="P1") + row=layout.row(align=align) + if func > 2: + row.prop(tex.pov, "func_P2", text="P2") + if func > 3: + row.prop(tex.pov, "func_P3", text="P3") + row=layout.row(align=align) + if func > 4: + row.prop(tex.pov, "func_P4", text="P4") + if func > 5: + row.prop(tex.pov, "func_P5", text="P5") + row=layout.row(align=align) + if func > 6: + row.prop(tex.pov, "func_P6", text="P6") + if func > 7: + row.prop(tex.pov, "func_P7", text="P7") + row=layout.row(align=align) + row.prop(tex.pov, "func_P8", text="P8") + row.prop(tex.pov, "func_P9", text="P9") + ###################################################End Patterns############################ + + + layout.prop(tex.pov, "warp_types", text="Warp types") #warp + if tex.pov.warp_types == "TOROIDAL": + layout.prop(tex.pov, "warp_tor_major_radius", text="Major radius") + if tex.pov.warp_types not in {"CUBIC","NONE"}: + layout.prop(tex.pov, "warp_orientation", text="Warp orientation") + col = layout.column(align=align) + row = col.row() + row.prop(tex.pov, "warp_dist_exp", text="Distance exponent") + row = col.row() + row.prop(tex.pov, "modifier_frequency", text="Frequency") + row.prop(tex.pov, "modifier_phase", text="Phase") + + row=layout.row() + + row.label(text="Offset:") + row.label(text="Scale:") + row.label(text="Rotate:") + col=layout.column(align=align) + row=col.row() + row.prop(tex.pov, "tex_mov_x", text="X") + row.prop(tex.pov, "tex_scale_x", text="X") + row.prop(tex.pov, "tex_rot_x", text="X") + row=col.row() + row.prop(tex.pov, "tex_mov_y", text="Y") + row.prop(tex.pov, "tex_scale_y", text="Y") + row.prop(tex.pov, "tex_rot_y", text="Y") + row=col.row() + row.prop(tex.pov, "tex_mov_z", text="Z") + row.prop(tex.pov, "tex_scale_z", text="Z") + row.prop(tex.pov, "tex_rot_z", text="Z") + row=layout.row() + + row.label(text="Turbulence:") + col=layout.column(align=align) + row=col.row() + row.prop(tex.pov, "warp_turbulence_x", text="X") + row.prop(tex.pov, "modifier_octaves", text="Octaves") + row=col.row() + row.prop(tex.pov, "warp_turbulence_y", text="Y") + row.prop(tex.pov, "modifier_lambda", text="Lambda") + row=col.row() + row.prop(tex.pov, "warp_turbulence_z", text="Z") + row.prop(tex.pov, "modifier_omega", text="Omega") + class TEXTURE_PT_povray_tex_gamma(TextureButtonsPanel, bpy.types.Panel): bl_label = "Image Gamma" COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -508,7 +781,7 @@ class TEXTURE_PT_povray_tex_gamma(TextureButtonsPanel, bpy.types.Panel): def draw_header(self, context): tex = context.texture - self.layout.prop(tex.pov, "tex_gamma_enable", text="") + self.layout.prop(tex.pov, "tex_gamma_enable", text="", icon='SEQ_LUMA_WAVEFORM') def draw(self, context): layout = self.layout -- GitLab