diff options
author | Maurice Raybaud <mauriceraybaud@hotmail.fr> | 2019-12-08 23:41:58 +0300 |
---|---|---|
committer | Maurice Raybaud <mauriceraybaud@hotmail.fr> | 2019-12-08 23:42:14 +0300 |
commit | 865d54f15575ffdfa7c82cfb7bd156928adeed81 (patch) | |
tree | 60307d9b21323c787a649bbd6ab7d15d1694d65b /render_povray | |
parent | 90d3e69f6597f9d0a3b670b41441cb5ae5ebabe2 (diff) |
POV: added doc strings
Hoping it will help the code to be less repulsive to new new developers.
Diffstat (limited to 'render_povray')
-rw-r--r-- | render_povray/__init__.py | 118 | ||||
-rw-r--r-- | render_povray/primitives.py | 573 | ||||
-rw-r--r-- | render_povray/render.py | 68 | ||||
-rw-r--r-- | render_povray/shading.py | 13 | ||||
-rw-r--r-- | render_povray/update_files.py | 3 |
5 files changed, 531 insertions, 244 deletions
diff --git a/render_povray/__init__.py b/render_povray/__init__.py index 96d1319c..f343db66 100644 --- a/render_povray/__init__.py +++ b/render_povray/__init__.py @@ -18,6 +18,78 @@ # <pep8 compliant> +"""Import, export and render to POV engines. + +These engines can be POV-Ray or Uberpov but others too, since POV is a +Scene Description Language. The script has been split in as few files +as possible : + +___init__.py : + Initialize variables + +update_files.py + Update new variables to values from older API. This file needs an update. + +ui.py : + Provide property buttons for the user to set up the variables. + +primitives.py : + Display some POV native primitives in 3D view for input and output. + +shading.py + Translate shading properties to declared textures at the top of a pov file + +nodes.py + Translate node trees to the pov file + +df3.py + Render smoke to *.df3 files + +render.py : + Translate geometry and UI properties (Blender and POV native) to the POV file + + +Along these essential files also coexist a few additional libraries to help make +Blender stand up to other POV IDEs such as povwin or QTPOV. + presets : + Material (sss) + apple.py ; chicken.py ; cream.py ; Ketchup.py ; marble.py ; + potato.py ; skim_milk.py ; skin1.py ; skin2.py ; whole_milk.py + Radiosity + 01_Debug.py ; 02_Fast.py ; 03_Normal.py ; 04_Two_Bounces.py ; + 05_Final.py ; 06_Outdoor_Low_Quality.py ; 07_Outdoor_High_Quality.py ; + 08_Outdoor(Sun)Light.py ; 09_Indoor_Low_Quality.py ; + 10_Indoor_High_Quality.py ; + World + 01_Clear_Blue_Sky.py ; 02_Partly_Hazy_Sky.py ; 03_Overcast_Sky.py ; + 04_Cartoony_Sky.py ; 05_Under_Water.py ; + Light + 01_(5400K)_Direct_Sun.py ; 02_(5400K)_High_Noon_Sun.py ; + 03_(6000K)_Daylight_Window.py ; + 04_(6000K)_2500W_HMI_(Halogen_Metal_Iodide).py ; + 05_(4000K)_100W_Metal_Halide.py ; 06_(3200K)_100W_Quartz_Halogen.py ; + 07_(2850K)_100w_Tungsten.py ; 08_(2600K)_40w_Tungsten.py ; + 09_(5000K)_75W_Full_Spectrum_Fluorescent_T12.py ; + 10_(4300K)_40W_Vintage_Fluorescent_T12.py ; + 11_(5000K)_18W_Standard_Fluorescent_T8 ; + 12_(4200K)_18W_Cool_White_Fluorescent_T8.py ; + 13_(3000K)_18W_Warm_Fluorescent_T8.py ; + 14_(6500K)_54W_Grow_Light_Fluorescent_T5-HO.py ; + 15_(3200K)_40W_Induction_Fluorescent.py ; + 16_(2100K)_150W_High_Pressure_Sodium.py ; + 17_(1700K)_135W_Low_Pressure_Sodium.py ; + 18_(6800K)_175W_Mercury_Vapor.py ; 19_(5200K)_700W_Carbon_Arc.py ; + 20_(6500K)_15W_LED_Spot.py ; 21_(2700K)_7W_OLED_Panel.py ; + 22_(30000K)_40W_Black_Light_Fluorescent.py ; + 23_(30000K)_40W_Black_Light_Bulb.py; 24_(1850K)_Candle.py + templates: + abyss.pov ; biscuit.pov ; bsp_Tango.pov ; chess2.pov ; + cornell.pov ; diffract.pov ; diffuse_back.pov ; float5 ; + gamma_showcase.pov ; grenadine.pov ; isocacti.pov ; + mediasky.pov ; patio-radio.pov ; subsurface.pov ; wallstucco.pov +""" + + bl_info = { "name": "Persistence of Vision", "author": "Campbell Barton, " @@ -71,6 +143,7 @@ else: ) def string_strip_hyphen(name): + """Remove hyphen characters from a string to avoid POV errors.""" return name.replace("-", "") def active_texture_name_from_uilist(self,context): @@ -98,6 +171,7 @@ def active_texture_name_from_search(self,context): # Scene POV properties. ############################################################################### class RenderPovSettingsScene(PropertyGroup): + """Declare scene level properties controllable in UI and translated to POV.""" #Linux SDL-window enable sdl_window_enable: BoolProperty( name="Enable SDL window", @@ -583,6 +657,7 @@ class RenderPovSettingsScene(PropertyGroup): # Material POV properties. ############################################################################### class MaterialTextureSlot(PropertyGroup): + """Declare material texture slot level properties for UI and translated to POV.""" bl_idname="pov_texture_slots", bl_description="Texture_slots from Blender-2.79", @@ -984,7 +1059,8 @@ bpy.types.ID.active_texture_index = IntProperty( default = 0) class RenderPovSettingsMaterial(PropertyGroup): -######################Begin Old Blender Internal Props######################### + """Declare material level properties controllable in UI and translated to POV.""" + ######################Begin Old Blender Internal Props######################### #former Space properties from removed Blender Internal use_limited_texture_context: BoolProperty( name="", @@ -1558,7 +1634,8 @@ class RenderPovSettingsMaterial(PropertyGroup): object_preview_rotate: FloatVectorProperty(name="Rotate", description="", min=-180.0, max=180.0,default=(0.0,0.0,0.0), subtype='XYZ') object_preview_bgcontrast: FloatProperty(name="Contrast", min=0.0, max=1.0, default=0.5) -class MaterialRaytraceTransparency(PropertyGroup): +class MaterialRaytraceTransparency(PropertyGroup): + """Declare transparency panel properties controllable in UI and translated to POV.""" depth: IntProperty( name="Depth", @@ -1614,6 +1691,8 @@ class MaterialRaytraceTransparency(PropertyGroup): min=-0.0, max=10.0, soft_min=0.25, soft_max=4.0, default=1.3) class MaterialRaytraceMirror(PropertyGroup): + """Declare reflection panel properties controllable in UI and translated to POV.""" + bl_description = "Raytraced reflection settings for the Material", use: BoolProperty( name="Mirror", @@ -1689,6 +1768,8 @@ class MaterialRaytraceMirror(PropertyGroup): min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=1.0, precision=3) class MaterialSubsurfaceScattering(PropertyGroup): + r"""Declare SSS/SSTL properties controllable in UI and translated to POV.""" + bl_description = "Subsurface scattering settings for the material", use: BoolProperty( @@ -1747,6 +1828,8 @@ class MaterialSubsurfaceScattering(PropertyGroup): min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.0, precision=3) class MaterialStrandSettings(PropertyGroup): + """Declare strand properties controllable in UI and translated to POV.""" + bl_description = "Strand settings for the material", blend_distance: FloatProperty( @@ -3099,6 +3182,8 @@ node_categories = [ # Texture POV properties. ############################################################################### class RenderPovSettingsTexture(PropertyGroup): + """Declare texture level properties controllable in UI and translated to POV.""" + #former Space properties from removed Blender Internal active_texture_index: IntProperty( name = "Index for texture_slots", @@ -3618,6 +3703,8 @@ class RenderPovSettingsTexture(PropertyGroup): ############################################################################### class RenderPovSettingsObject(PropertyGroup): + """Declare object and primitives level properties controllable in UI and translated to POV.""" + # Pov inside_vector used for CSG inside_vector: FloatVectorProperty( name="CSG Inside Vector", description="Direction to shoot CSG inside test rays at", @@ -3767,14 +3854,17 @@ class RenderPovSettingsObject(PropertyGroup): def prop_update_cylinder(self, context): + """Update POV cylinder primitive parameters not only at creation but anytime they are changed in UI.""" if bpy.ops.pov.cylinder_update.poll(): bpy.ops.pov.cylinder_update() - cylinder_radius: FloatProperty(name="Cylinder R",min=0.00, max=10.0, default=0.04, update=prop_update_cylinder) + + cylinder_radius: FloatProperty( + name="Cylinder R",min=0.00, max=10.0, default=0.04, update=prop_update_cylinder) + cylinder_location_cap: FloatVectorProperty( name="Cylinder Cap Location", subtype='TRANSLATION', description="The position of the 'other' end of the cylinder (relative to object location)", - default=(0.0, 0.0, 2.0), update=prop_update_cylinder, - ) + default=(0.0, 0.0, 2.0), update=prop_update_cylinder) imported_cyl_loc: FloatVectorProperty( name="Imported Pov location", @@ -3787,16 +3877,21 @@ class RenderPovSettingsObject(PropertyGroup): default=(0.0, 0.0, 2.0)) def prop_update_sphere(self, context): + """Update POV sphere primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.sphere_update() - sphere_radius: FloatProperty(name="Sphere radius",min=0.00, max=10.0, default=0.5, update=prop_update_sphere) + + sphere_radius: FloatProperty( + name="Sphere radius",min=0.00, max=10.0, default=0.5, update=prop_update_sphere) def prop_update_cone(self, context): + """Update POV cone primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.cone_update() cone_base_radius: FloatProperty( name = "Base radius", description = "The first radius of the cone", default = 1.0, min = 0.01, max = 100.0, update=prop_update_cone) + cone_cap_radius: FloatProperty( name = "Cap radius", description = "The second radius of the cone", default = 0.3, min = 0.0, max = 100.0, update=prop_update_cone) @@ -3810,10 +3905,12 @@ class RenderPovSettingsObject(PropertyGroup): default = 2.0, min = 0.01, max = 100.0, update=prop_update_cone) cone_base_z: FloatProperty() + cone_cap_z: FloatProperty() ###########Parametric def prop_update_parametric(self, context): + """Update POV parametric surface primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.parametric_update() u_min: FloatProperty(name = "U Min", @@ -3838,6 +3935,7 @@ class RenderPovSettingsObject(PropertyGroup): ###########Torus def prop_update_torus(self, context): + """Update POV torus primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.torus_update() torus_major_segments: IntProperty( @@ -3899,6 +3997,7 @@ class RenderPovSettingsObject(PropertyGroup): ##############Superellipsoid def prop_update_superellipsoid(self, context): + """Update POV superellipsoid primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.superellipsoid_update() se_param1: FloatProperty( @@ -3948,6 +4047,7 @@ class RenderPovSettingsObject(PropertyGroup): #############Supertorus def prop_update_supertorus(self, context): + """Update POV supertorus primitive parameters not only at creation but anytime they are changed in UI.""" bpy.ops.pov.supertorus_update() st_major_radius: FloatProperty( @@ -4089,6 +4189,7 @@ class RenderPovSettingsObject(PropertyGroup): # Camera POV properties. ############################################################################### class RenderPovSettingsCamera(PropertyGroup): + """Declare camera properties controllable in UI and translated to POV.""" #DOF Toggle dof_enable: BoolProperty( name="Depth Of Field", description="Enable POV Depth Of Field ", @@ -4153,6 +4254,7 @@ class RenderPovSettingsCamera(PropertyGroup): # Light POV properties. ############################################################################### class RenderPovSettingsLight(PropertyGroup): + """Declare light properties controllable in UI and translated to POV.""" #former Space properties from removed Blender Internal use_limited_texture_context: BoolProperty( name="", @@ -4207,6 +4309,7 @@ class RenderPovSettingsLight(PropertyGroup): # World POV properties. ############################################################################### class RenderPovSettingsWorld(PropertyGroup): + """Declare world properties controllable in UI and translated to POV.""" #former Space properties from removed Blender Internal use_limited_texture_context: BoolProperty( name="", @@ -4255,6 +4358,7 @@ class RenderPovSettingsWorld(PropertyGroup): name = "Index for texture_slots", default = 0) class WorldTextureSlot(PropertyGroup): + """Declare world texture slot properties controllable in UI and translated to POV.""" blend_factor: FloatProperty( name="Blend", description="Amount texture affects color progression of the " @@ -4352,6 +4456,7 @@ class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList): # Text POV properties. ############################################################################### class RenderPovSettingsText(PropertyGroup): + """Declare text properties to use UI as an IDE or render text snippets to POV.""" custom_code: EnumProperty( name="Custom Code", description="rendered source: Both adds text at the " @@ -4365,6 +4470,7 @@ class RenderPovSettingsText(PropertyGroup): # Povray Preferences. ############################################################################### class PovrayPreferences(AddonPreferences): + """Declare preference variables to set up POV binary.""" bl_idname = __name__ branch_feature_set_povray: EnumProperty( diff --git a/render_povray/primitives.py b/render_povray/primitives.py index 75aa2d25..c1e37ab3 100644 --- a/render_povray/primitives.py +++ b/render_povray/primitives.py @@ -47,6 +47,7 @@ from mathutils import ( #import collections def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True): + """Generate proxy mesh.""" if mesh is None: mesh = bpy.data.meshes.new(name) mesh.from_pydata(verts, edges, faces) @@ -60,6 +61,7 @@ def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True): class POVRAY_OT_lathe_add(bpy.types.Operator): + """Add the representation of POV lathe using a screw modifier.""" bl_idname = "pov.addlathe" bl_label = "Lathe" bl_options = {'REGISTER','UNDO'} @@ -91,123 +93,125 @@ class POVRAY_OT_lathe_add(bpy.types.Operator): def pov_superellipsoid_define(context, op, ob): + """Create the proxy mesh of a POV superellipsoid using the pov_superellipsoid_define() function.""" - if op: - mesh = None + if op: + mesh = None - u = op.se_u - v = op.se_v - n1 = op.se_n1 - n2 = op.se_n2 - edit = op.se_edit - se_param1 = n2 # op.se_param1 - se_param2 = n1 # op.se_param2 + u = op.se_u + v = op.se_v + n1 = op.se_n1 + n2 = op.se_n2 + edit = op.se_edit + se_param1 = n2 # op.se_param1 + se_param2 = n1 # op.se_param2 - else: - assert(ob) - mesh = ob.data + else: + assert(ob) + mesh = ob.data - u = ob.pov.se_u - v = ob.pov.se_v - n1 = ob.pov.se_n1 - n2 = ob.pov.se_n2 - edit = ob.pov.se_edit - se_param1 = ob.pov.se_param1 - se_param2 = ob.pov.se_param2 + u = ob.pov.se_u + v = ob.pov.se_v + n1 = ob.pov.se_n1 + n2 = ob.pov.se_n2 + edit = ob.pov.se_edit + se_param1 = ob.pov.se_param1 + se_param2 = ob.pov.se_param2 - verts = [] - r=1 - - stepSegment=360/v*pi/180 - stepRing=pi/u - angSegment=0 - angRing=-pi/2 - - step=0 - for ring in range(0,u-1): - angRing += stepRing - for segment in range(0,v): - step += 1 - angSegment += stepSegment - x = r*(abs(cos(angRing))**n1)*(abs(cos(angSegment))**n2) - if (cos(angRing) < 0 and cos(angSegment) > 0) or \ - (cos(angRing) > 0 and cos(angSegment) < 0): - x = -x - y = r*(abs(cos(angRing))**n1)*(abs(sin(angSegment))**n2) - if (cos(angRing) < 0 and sin(angSegment) > 0) or \ - (cos(angRing) > 0 and sin(angSegment) < 0): - y = -y - z = r*(abs(sin(angRing))**n1) - if sin(angRing) < 0: - z = -z - x = round(x,4) - y = round(y,4) - z = round(z,4) - verts.append((x,y,z)) - if edit == 'TRIANGLES': - verts.append((0,0,1)) - verts.append((0,0,-1)) + verts = [] + r=1 + + stepSegment=360/v*pi/180 + stepRing=pi/u + angSegment=0 + angRing=-pi/2 + + step=0 + for ring in range(0,u-1): + angRing += stepRing + for segment in range(0,v): + step += 1 + angSegment += stepSegment + x = r*(abs(cos(angRing))**n1)*(abs(cos(angSegment))**n2) + if (cos(angRing) < 0 and cos(angSegment) > 0) or \ + (cos(angRing) > 0 and cos(angSegment) < 0): + x = -x + y = r*(abs(cos(angRing))**n1)*(abs(sin(angSegment))**n2) + if (cos(angRing) < 0 and sin(angSegment) > 0) or \ + (cos(angRing) > 0 and sin(angSegment) < 0): + y = -y + z = r*(abs(sin(angRing))**n1) + if sin(angRing) < 0: + z = -z + x = round(x,4) + y = round(y,4) + z = round(z,4) + verts.append((x,y,z)) + if edit == 'TRIANGLES': + verts.append((0,0,1)) + verts.append((0,0,-1)) - faces = [] + faces = [] - for i in range(0,u-2): - m=i*v - for p in range(0,v): - if p < v-1: - face=(m+p,1+m+p,v+1+m+p,v+m+p) - if p == v-1: - face=(m+p,m,v+m,v+m+p) - faces.append(face) - if edit == 'TRIANGLES': - indexUp=len(verts)-2 - indexDown=len(verts)-1 - indexStartDown=len(verts)-2-v - for i in range(0,v): - if i < v-1: - face=(indexDown,i,i+1) - faces.append(face) - if i == v-1: - face=(indexDown,i,0) - faces.append(face) - for i in range(0,v): - if i < v-1: - face=(indexUp,i+indexStartDown,i+indexStartDown+1) - faces.append(face) - if i == v-1: - face=(indexUp,i+indexStartDown,indexStartDown) - faces.append(face) - if edit == 'NGONS': - face=[] - for i in range(0,v): - face.append(i) - faces.append(face) - face=[] - indexUp=len(verts)-1 - for i in range(0,v): - face.append(indexUp-i) + for i in range(0,u-2): + m=i*v + for p in range(0,v): + if p < v-1: + face=(m+p,1+m+p,v+1+m+p,v+m+p) + if p == v-1: + face=(m+p,m,v+m,v+m+p) faces.append(face) - mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid") + if edit == 'TRIANGLES': + indexUp=len(verts)-2 + indexDown=len(verts)-1 + indexStartDown=len(verts)-2-v + for i in range(0,v): + if i < v-1: + face=(indexDown,i,i+1) + faces.append(face) + if i == v-1: + face=(indexDown,i,0) + faces.append(face) + for i in range(0,v): + if i < v-1: + face=(indexUp,i+indexStartDown,i+indexStartDown+1) + faces.append(face) + if i == v-1: + face=(indexUp,i+indexStartDown,indexStartDown) + faces.append(face) + if edit == 'NGONS': + face=[] + for i in range(0,v): + face.append(i) + faces.append(face) + face=[] + indexUp=len(verts)-1 + for i in range(0,v): + face.append(indexUp-i) + faces.append(face) + mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid") - if not ob: - ob = object_utils.object_data_add(context, mesh, operator=None) - #engine = context.scene.render.engine what for? - ob = context.object - ob.name = ob.data.name = "PovSuperellipsoid" - ob.pov.object_as = 'SUPERELLIPSOID' - ob.pov.se_param1 = n2 - ob.pov.se_param2 = n1 - - ob.pov.se_u = u - ob.pov.se_v = v - ob.pov.se_n1 = n1 - ob.pov.se_n2 = n2 - ob.pov.se_edit = edit - - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + if not ob: + ob = object_utils.object_data_add(context, mesh, operator=None) + #engine = context.scene.render.engine what for? + ob = context.object + ob.name = ob.data.name = "PovSuperellipsoid" + ob.pov.object_as = 'SUPERELLIPSOID' + ob.pov.se_param1 = n2 + ob.pov.se_param2 = n1 + + ob.pov.se_u = u + ob.pov.se_v = v + ob.pov.se_n1 = n1 + ob.pov.se_n2 = n2 + ob.pov.se_edit = edit + + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_superellipsoid_add(bpy.types.Operator): + """Add the representation of POV superellipsoid using the pov_superellipsoid_define() function.""" bl_idname = "pov.addsuperellipsoid" bl_label = "Add SuperEllipsoid" bl_description = "Create a SuperEllipsoid" @@ -258,6 +262,11 @@ class POVRAY_OT_superellipsoid_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_superellipsoid_update(bpy.types.Operator): + """Update the superellipsoid. + + Delete its previous proxy geometry and rerun pov_superellipsoid_define() function + with the new parameters""" + bl_idname = "pov.superellipsoid_update" bl_label = "Update" bl_description = "Update Superellipsoid" @@ -406,6 +415,8 @@ def pov_supertorus_define(context, op, ob): ob.pov.st_edit = st_edit class POVRAY_OT_supertorus_add(bpy.types.Operator): + """Add the representation of POV supertorus using the pov_supertorus_define() function.""" + bl_idname = "pov.addsupertorus" bl_label = "Add Supertorus" bl_description = "Create a SuperTorus" @@ -450,6 +461,10 @@ class POVRAY_OT_supertorus_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_supertorus_update(bpy.types.Operator): + """Update the supertorus. + + Delete its previous proxy geometry and rerun pov_supetorus_define() function + with the new parameters""" bl_idname = "pov.supertorus_update" bl_label = "Update" bl_description = "Update SuperTorus" @@ -474,6 +489,8 @@ class POVRAY_OT_supertorus_update(bpy.types.Operator): return {'FINISHED'} ######################################################################################################### class POVRAY_OT_loft_add(bpy.types.Operator): + """Create the representation of POV loft using Blender curves.""" + bl_idname = "pov.addloft" bl_label = "Add Loft Data" bl_description = "Create a Curve data for Meshmaker" @@ -588,6 +605,11 @@ class POVRAY_OT_loft_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_plane_add(bpy.types.Operator): + """Add the representation of POV infinite plane using just a very big Blender Plane. + + Flag its primitive type with a specific pov.object_as attribute and lock edit mode + to keep proxy consistency by hiding edit geometry.""" + bl_idname = "pov.addplane" bl_label = "Plane" bl_description = "Add Plane" @@ -609,6 +631,11 @@ class POVRAY_OT_plane_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_box_add(bpy.types.Operator): + """Add the representation of POV box using a simple Blender mesh cube. + + Flag its primitive type with a specific pov.object_as attribute and lock edit mode + to keep proxy consistency by hiding edit geometry.""" + bl_idname = "pov.addbox" bl_label = "Box" bl_description = "Add Box" @@ -664,6 +691,9 @@ def pov_cylinder_define(context, op, ob, radius, loc, loc_cap): class POVRAY_OT_cylinder_add(bpy.types.Operator): + """Add the representation of POV cylinder using pov_cylinder_define() function. + + Use imported_cyl_loc when this operator is run by POV importer.""" bl_idname = "pov.addcylinder" bl_label = "Cylinder" bl_description = "Add Cylinder" @@ -709,6 +739,11 @@ class POVRAY_OT_cylinder_add(bpy.types.Operator): class POVRAY_OT_cylinder_update(bpy.types.Operator): + """Update the POV cylinder. + + Delete its previous proxy geometry and rerun pov_cylinder_define() function + with the new parameters""" + bl_idname = "pov.cylinder_update" bl_label = "Update" bl_description = "Update Cylinder" @@ -734,44 +769,53 @@ class POVRAY_OT_cylinder_update(bpy.types.Operator): ################################SPHERE########################################## def pov_sphere_define(context, op, ob, loc): - if op: - R = op.R - loc = bpy.context.scene.cursor.location - else: - assert(ob) - R = ob.pov.sphere_radius + """create the representation of POV sphere using a Blender icosphere. - #keep object rotation and location for the add object operator - obrot = ob.rotation_euler - #obloc = ob.location - obscale = ob.scale + Its nice platonic solid curvature better represents pov rendertime + tesselation than a UV sphere""" - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.reveal() - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.mesh.delete(type='VERT') - bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius, location=loc, rotation=obrot) - #bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL') - bpy.ops.transform.resize(value=obscale) - #bpy.ops.transform.rotate(axis=obrot, proportional_size=1) + if op: + R = op.R + loc = bpy.context.scene.cursor.location + else: + assert(ob) + R = ob.pov.sphere_radius + + #keep object rotation and location for the add object operator + obrot = ob.rotation_euler + #obloc = ob.location + obscale = ob.scale + + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.reveal() + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.delete(type='VERT') + bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius, location=loc, rotation=obrot) + #bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL') + bpy.ops.transform.resize(value=obscale) + #bpy.ops.transform.rotate(axis=obrot, proportional_size=1) - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") - bpy.ops.object.shade_smooth() - #bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL') + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") + bpy.ops.object.shade_smooth() + #bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL') - if not ob: - bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=R, location=loc) - ob = context.object - ob.name = ob.data.name = "PovSphere" - ob.pov.object_as = "SPHERE" - ob.pov.sphere_radius = R - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + if not ob: + bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=R, location=loc) + ob = context.object + ob.name = ob.data.name = "PovSphere" + ob.pov.object_as = "SPHERE" + ob.pov.sphere_radius = R + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_sphere_add(bpy.types.Operator): + """Add the representation of POV sphere using pov_sphere_define() function. + + Use imported_loc when this operator is run by POV importer.""" + bl_idname = "pov.addsphere" bl_label = "Sphere" bl_description = "Add Sphere Shape" @@ -823,6 +867,11 @@ class POVRAY_OT_sphere_add(bpy.types.Operator): # ob.name = ob.data.name = 'PovSphere' # return {'FINISHED'} class POVRAY_OT_sphere_update(bpy.types.Operator): + """Update the POV sphere. + + Delete its previous proxy geometry and rerun pov_sphere_define() function + with the new parameters""" + bl_idname = "pov.sphere_update" bl_label = "Update" bl_description = "Update Sphere" @@ -844,6 +893,9 @@ class POVRAY_OT_sphere_update(bpy.types.Operator): ####################################CONE####################################### def pov_cone_define(context, op, ob): + """Add the representation of POV cone using pov_define_mesh() function. + + Blender cone does not offer the same features such as a second radius.""" verts = [] faces = [] if op: @@ -903,13 +955,15 @@ def pov_cone_define(context, op, ob): class POVRAY_OT_cone_add(bpy.types.Operator): + """Add the representation of POV cone using pov_cone_define() function.""" + bl_idname = "pov.cone_add" bl_label = "Cone" bl_description = "Add Cone" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} - # XXX Keep it in sync with __init__'s RenderPovSettingsConePrimitive + # XXX Keep it in sync with __init__.py's RenderPovSettingsConePrimitive # If someone knows how to define operators' props from a func, I'd be delighted to learn it! base: FloatProperty( name = "Base radius", description = "The first radius of the cone", @@ -937,6 +991,11 @@ class POVRAY_OT_cone_add(bpy.types.Operator): class POVRAY_OT_cone_update(bpy.types.Operator): + """Update the POV cone. + + Delete its previous proxy geometry and rerun pov_cone_define() function + with the new parameters""" + bl_idname = "pov.cone_update" bl_label = "Update" bl_description = "Update Cone" @@ -959,9 +1018,15 @@ class POVRAY_OT_cone_update(bpy.types.Operator): pov_cone_define(context, None, context.object) return {'FINISHED'} -######################################################################################################### + +########################################ISOSURFACES################################## class POVRAY_OT_isosurface_box_add(bpy.types.Operator): + """Add the representation of POV isosurface box using also just a Blender mesh cube. + + Flag its primitive type with a specific pov.object_as attribute and lock edit mode + to keep proxy consistency by hiding edit geometry.""" + bl_idname = "pov.addisosurfacebox" bl_label = "Isosurface Box" bl_description = "Add Isosurface contained by Box" @@ -984,6 +1049,11 @@ class POVRAY_OT_isosurface_box_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): + """Add the representation of POV isosurface sphere by a Blender mesh icosphere. + + Flag its primitive type with a specific pov.object_as attribute and lock edit mode + to keep proxy consistency by hiding edit geometry.""" + bl_idname = "pov.addisosurfacesphere" bl_label = "Isosurface Sphere" bl_description = "Add Isosurface contained by Sphere" @@ -1007,6 +1077,11 @@ class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): + """Add the representation of POV sphere_sweep using a Blender NURBS curve. + + Flag its primitive type with a specific ob.pov.curveshape attribute and + leave access to edit mode to keep user editable handles.""" + bl_idname = "pov.addspheresweep" bl_label = "Sphere Sweep" bl_description = "Create Sphere Sweep along curve" @@ -1027,6 +1102,11 @@ class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_blob_add(bpy.types.Operator): + """Add the representation of POV blob using a Blender meta ball. + + No need to flag its primitive type as meta are exported to blobs + and leave access to edit mode to keep user editable thresholds.""" + bl_idname = "pov.addblobsphere" bl_label = "Blob Sphere" bl_description = "Add Blob Sphere" @@ -1042,6 +1122,15 @@ class POVRAY_OT_blob_add(bpy.types.Operator): class POVRAY_OT_rainbow_add(bpy.types.Operator): + """Add the representation of POV rainbow using a Blender spot light. + + Rainbows indeed propagate along a visibility cone. + Flag its primitive type with a specific ob.pov.object_as attribute + and leave access to edit mode to keep user editable handles. + Add a constraint to orient it towards camera because POV Rainbows + are view dependant and having it always initially visible is less + confusing """ + bl_idname = "pov.addrainbow" bl_label = "Rainbow" bl_description = "Add Rainbow" @@ -1076,6 +1165,11 @@ class POVRAY_OT_rainbow_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper): + """Add the representation of POV height_field using a displaced grid. + + texture slot fix and displace modifier will be needed because noise + displace operator was deprecated in 2.8""" + bl_idname = "pov.addheightfield" bl_label = "Height Field" bl_description = "Add Height Field " @@ -1159,47 +1253,54 @@ class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper): ############################TORUS############################################ def pov_torus_define(context, op, ob): - if op: - mas = op.mas - mis = op.mis - mar = op.mar - mir = op.mir - else: - assert(ob) - mas = ob.pov.torus_major_segments - mis = ob.pov.torus_minor_segments - mar = ob.pov.torus_major_radius - mir = ob.pov.torus_minor_radius + """Add the representation of POV torus using just a Blender torus. - #keep object rotation and location for the add object operator - obrot = ob.rotation_euler - obloc = ob.location + But flag its primitive type with a specific pov.object_as attribute and lock edit mode + to keep proxy consistency by hiding edit geometry.""" - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.reveal() - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.mesh.delete(type='VERT') - bpy.ops.mesh.primitive_torus_add(rotation = obrot, location = obloc, major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) + if op: + mas = op.mas + mis = op.mis + mar = op.mar + mir = op.mir + else: + assert(ob) + mas = ob.pov.torus_major_segments + mis = ob.pov.torus_minor_segments + mar = ob.pov.torus_major_radius + mir = ob.pov.torus_minor_radius + + #keep object rotation and location for the add object operator + obrot = ob.rotation_euler + obloc = ob.location + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.reveal() + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.delete(type='VERT') + bpy.ops.mesh.primitive_torus_add(rotation = obrot, location = obloc, major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") - if not ob: - bpy.ops.mesh.primitive_torus_add(major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) - ob = context.object - ob.name = ob.data.name = "PovTorus" - ob.pov.object_as = "TORUS" - ob.pov.torus_major_segments = mas - ob.pov.torus_minor_segments = mis - ob.pov.torus_major_radius = mar - ob.pov.torus_minor_radius = mir - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + + if not ob: + bpy.ops.mesh.primitive_torus_add(major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) + ob = context.object + ob.name = ob.data.name = "PovTorus" + ob.pov.object_as = "TORUS" + ob.pov.torus_major_segments = mas + ob.pov.torus_minor_segments = mis + ob.pov.torus_major_radius = mar + ob.pov.torus_minor_radius = mir + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_torus_add(bpy.types.Operator): + """Add the representation of POV torus using using pov_torus_define() function.""" + bl_idname = "pov.addtorus" bl_label = "Torus" bl_description = "Add Torus" @@ -1231,6 +1332,11 @@ class POVRAY_OT_torus_add(bpy.types.Operator): class POVRAY_OT_torus_update(bpy.types.Operator): + """Update the POV torus. + + Delete its previous proxy geometry and rerun pov_torus_define() function + with the new parameters""" + bl_idname = "pov.torus_update" bl_label = "Update" bl_description = "Update Torus" @@ -1253,6 +1359,8 @@ class POVRAY_OT_torus_update(bpy.types.Operator): class POVRAY_OT_prism_add(bpy.types.Operator): + """Add the representation of POV prism using using an extruded curve.""" + bl_idname = "pov.addprism" bl_label = "Prism" bl_description = "Create Prism" @@ -1300,65 +1408,70 @@ class POVRAY_OT_prism_add(bpy.types.Operator): ##############################PARAMETRIC###################################### def pov_parametric_define(context, op, ob): - if op: - u_min = op.u_min - u_max = op.u_max - v_min = op.v_min - v_max = op.v_max - x_eq = op.x_eq - y_eq = op.y_eq - z_eq = op.z_eq + """Add the representation of POV parametric surfaces by math surface from add mesh extra objects addon.""" - else: - assert(ob) - u_min = ob.pov.u_min - u_max = ob.pov.u_max - v_min = ob.pov.v_min - v_max = ob.pov.v_max - x_eq = ob.pov.x_eq - y_eq = ob.pov.y_eq - z_eq = ob.pov.z_eq - - #keep object rotation and location for the updated object - obloc = ob.location - obrot = ob.rotation_euler # In radians - #Parametric addon has no loc rot, some extra work is needed - #in case cursor has moved - curloc = bpy.context.scene.cursor.location - - - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.reveal() - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.mesh.delete(type='VERT') - bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) - bpy.ops.mesh.select_all(action='SELECT') - #extra work: - bpy.ops.transform.translate(value=(obloc-curloc), proportional_size=1) - bpy.ops.transform.rotate(axis=obrot, proportional_size=1) + if op: + u_min = op.u_min + u_max = op.u_max + v_min = op.v_min + v_max = op.v_max + x_eq = op.x_eq + y_eq = op.y_eq + z_eq = op.z_eq - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + else: + assert(ob) + u_min = ob.pov.u_min + u_max = ob.pov.u_max + v_min = ob.pov.v_min + v_max = ob.pov.v_max + x_eq = ob.pov.x_eq + y_eq = ob.pov.y_eq + z_eq = ob.pov.z_eq + + #keep object rotation and location for the updated object + obloc = ob.location + obrot = ob.rotation_euler # In radians + #Parametric addon has no loc rot, some extra work is needed + #in case cursor has moved + curloc = bpy.context.scene.cursor.location - if not ob: - bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) - ob = context.object - ob.name = ob.data.name = "PovParametric" - ob.pov.object_as = "PARAMETRIC" - - ob.pov.u_min = u_min - ob.pov.u_max = u_max - ob.pov.v_min = v_min - ob.pov.v_max = v_max - ob.pov.x_eq = x_eq - ob.pov.y_eq = y_eq - ob.pov.z_eq = z_eq - - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.hide(unselected=False) - bpy.ops.object.mode_set(mode="OBJECT") + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.reveal() + bpy.ops.mesh.select_all(action='SELECT') + bpy.ops.mesh.delete(type='VERT') + bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) + bpy.ops.mesh.select_all(action='SELECT') + #extra work: + bpy.ops.transform.translate(value=(obloc-curloc), proportional_size=1) + bpy.ops.transform.rotate(axis=obrot, proportional_size=1) + + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") + + + if not ob: + bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) + ob = context.object + ob.name = ob.data.name = "PovParametric" + ob.pov.object_as = "PARAMETRIC" + + ob.pov.u_min = u_min + ob.pov.u_max = u_max + ob.pov.v_min = v_min + ob.pov.v_max = v_max + ob.pov.x_eq = x_eq + ob.pov.y_eq = y_eq + ob.pov.z_eq = z_eq + + bpy.ops.object.mode_set(mode="EDIT") + bpy.ops.mesh.hide(unselected=False) + bpy.ops.object.mode_set(mode="OBJECT") + class POVRAY_OT_parametric_add(bpy.types.Operator): + """Add the representation of POV parametric surfaces using pov_parametric_define() function.""" + bl_idname = "pov.addparametric" bl_label = "Parametric" bl_description = "Add Paramertic" @@ -1400,6 +1513,11 @@ class POVRAY_OT_parametric_add(bpy.types.Operator): return {'FINISHED'} class POVRAY_OT_parametric_update(bpy.types.Operator): + """Update the representation of POV parametric surfaces. + + Delete its previous proxy geometry and rerun pov_parametric_define() function + with the new parameters""" + bl_idname = "pov.parametric_update" bl_label = "Update" bl_description = "Update parametric object" @@ -1418,7 +1536,10 @@ class POVRAY_OT_parametric_update(bpy.types.Operator): return {'FINISHED'} ####################################################################### + class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator): + """Add the proxy mesh for POV Polygon to circle lofting macro""" + bl_idname = "pov.addpolygontocircle" bl_label = "Polygon To Circle Blending" bl_description = "Add Polygon To Circle Blending Surface" diff --git a/render_povray/render.py b/render_povray/render.py index 7fd8fca5..ec5b6689 100644 --- a/render_povray/render.py +++ b/render_povray/render.py @@ -40,6 +40,8 @@ from . import nodes # for POV specific nodes ##############################SF########################### ##############find image texture def imageFormat(imgF): + """Identify input image filetypes to transmit to POV.""" + # First use the below explicit extensions to identify image file prospects ext = { 'JPG': "jpeg", 'JPEG': "jpeg", @@ -54,7 +56,7 @@ def imageFormat(imgF): 'EXR': "exr", 'HDR': "hdr", }.get(os.path.splitext(imgF)[-1].upper(), "") - + # Then, use imghdr to really identify the filetype as it can be different if not ext: #maybe add a check for if path exists here? print(" WARNING: texture image has no extension") #too verbose @@ -64,6 +66,7 @@ def imageFormat(imgF): def imgMap(ts): + """Translate mapping type from Blender UI to POV syntax and return that string.""" image_map = "" if ts.mapping == 'FLAT': image_map = "map_type 0 " @@ -72,7 +75,7 @@ def imgMap(ts): elif ts.mapping == 'TUBE': image_map = "map_type 2 " - ## map_type 3 and 4 in development (?) + ## map_type 3 and 4 in development (?) (ENV in pov 3.8) ## for POV-Ray, currently they just seem to default back to Flat (type 0) #elif ts.mapping=="?": # image_map = " map_type 3 " @@ -93,6 +96,7 @@ def imgMap(ts): def imgMapTransforms(ts): + """Translate mapping transformations from Blender UI to POV syntax and return that string.""" # XXX TODO: unchecked textures give error of variable referenced before assignment XXX # POV-Ray "scale" is not a number of repetitions factor, but ,its # inverse, a standard scale factor. @@ -126,6 +130,7 @@ def imgMapTransforms(ts): return image_map_transforms def imgMapBG(wts): + """Translate world mapping from Blender UI to POV syntax and return that string.""" image_mapBG = "" # texture_coords refers to the mapping of world textures: if wts.texture_coords == 'VIEW' or wts.texture_coords == 'GLOBAL': @@ -150,6 +155,7 @@ def imgMapBG(wts): def path_image(image): + """Conform a path string to POV syntax to avoid POV errors.""" return bpy.path.abspath(image.filepath, library=image.library).replace("\\","/") # .replace("\\","/") to get only forward slashes as it's what POV prefers, # even on windows @@ -158,16 +164,24 @@ def path_image(image): def string_strip_hyphen(name): + """Remove hyphen characters from a string to avoid POV errors.""" return name.replace("-", "") def safety(name, Level): - # safety string name material - # - # Level=1 is for texture with No specular nor Mirror reflection - # Level=2 is for texture with translation of spec and mir levels - # for when no map influences them - # Level=3 is for texture with Maximum Spec and Mirror + """append suffix characters to names of various material declinations. + + Material declinations are necessary to POV syntax and used in shading.py + by the povHasnoSpecularMaps function to create the finish map trick and + the suffixes avoid name collisions. + Keyword arguments: + name -- the initial material name as a string + Level -- the enum number of the Level being written: + Level=1 is for texture with No specular nor Mirror reflection + Level=2 is for texture with translation of spec and mir levels + for when no map influences them + Level=3 is for texture with Maximum Spec and Mirror + """ try: if int(name) > 0: @@ -293,6 +307,11 @@ def write_global_setting(scene,file): file.write("}\n") ''' def write_object_modifiers(scene,ob,File): + """Translate some object level POV statements from Blender UI + to POV syntax and write to exported file """ + + # Maybe return that string to be added instead of directly written. + '''XXX WIP onceCSG = 0 for mod in ob.modifiers: @@ -352,6 +371,7 @@ def write_object_modifiers(scene,ob,File): def write_pov(filename, scene=None, info_callback=None): + """Main export process from Blender UI to POV syntax and write to exported file """ import mathutils #file = filename file = open(filename, "w") @@ -390,6 +410,7 @@ def write_pov(filename, scene=None, info_callback=None): tab = setTab(scene.pov.indentation_character, scene.pov.indentation_spaces) if not scene.pov.tempfiles_enable: def tabWrite(str_o): + """Indent POV syntax from brackets levels and write to exported file """ global tabLevel brackets = str_o.count("{") - str_o.count("}") + str_o.count("[") - str_o.count("]") if brackets < 0: @@ -404,9 +425,12 @@ def write_pov(filename, scene=None, info_callback=None): tabLevel = tabLevel + brackets else: def tabWrite(str_o): + """write directly to exported file if user checked autonamed temp files (faster).""" + file.write(str_o) def uniqueName(name, nameSeq): + """Increment any generated POV name that could get identical to avoid collisions""" if name not in nameSeq: name = string_strip_hyphen(name) @@ -421,6 +445,8 @@ def write_pov(filename, scene=None, info_callback=None): return name def writeMatrix(matrix): + """Translate some tranform matrix from Blender UI + to POV syntax and write to exported file """ tabWrite("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n" % (matrix[0][0], matrix[1][0], matrix[2][0], matrix[0][1], matrix[1][1], matrix[2][1], @@ -428,6 +454,8 @@ def write_pov(filename, scene=None, info_callback=None): matrix[0][3], matrix[1][3], matrix[2][3])) def MatrixAsPovString(matrix): + """Translate some tranform matrix from Blender UI + to POV syntax and return that string """ sMatrix = ("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n" % (matrix[0][0], matrix[1][0], matrix[2][0], matrix[0][1], matrix[1][1], matrix[2][1], @@ -436,7 +464,9 @@ def write_pov(filename, scene=None, info_callback=None): return sMatrix def writeObjectMaterial(material, ob): - + """Translate some object level material from Blender UI (VS data level) + to POV interior{} syntax and write it to exported file """ + # DH - modified some variables to be function local, avoiding RNA write # this should be checked to see if it is functionally correct @@ -517,6 +547,7 @@ def write_pov(filename, scene=None, info_callback=None): DEF_MAT_NAME = "" #or "Default"? def exportCamera(): + """Translate camera from Blender UI to POV syntax and write to exported file.""" camera = scene.camera # DH disabled for now, this isn't the correct context @@ -572,6 +603,7 @@ def write_pov(filename, scene=None, info_callback=None): def exportLamps(lamps): + """Translate lights from Blender UI to POV syntax and write to exported file.""" # Incremented after each lamp export to declare its target # currently used for Fresnel diffuse shader as their slope vector: global lampCount @@ -691,6 +723,7 @@ def write_pov(filename, scene=None, info_callback=None): #################################################################################################### def exportRainbows(rainbows): + """write all POV rainbows primitives to exported file """ for ob in rainbows: povdataname = ob.data.name #enough? angle = degrees(ob.data.spot_size/2.5) #radians in blender (2 @@ -758,6 +791,7 @@ def write_pov(filename, scene=None, info_callback=None): ################################XXX LOFT, ETC. def exportCurves(scene, ob): + """write all curves based POV primitives to exported file """ name_orig = "OB" + ob.name dataname_orig = "DATA" + ob.data.name @@ -1621,7 +1655,7 @@ def write_pov(filename, scene=None, info_callback=None): def exportMeta(metas): - + """write all POV blob primitives and Blender Metas to exported file """ # TODO - blenders 'motherball' naming is not supported. if comments and len(metas) >= 1: @@ -1802,6 +1836,7 @@ def write_pov(filename, scene=None, info_callback=None): DEF_OBJ_NAME = "Default" def exportMeshes(scene, sel, csg): + """write all meshes as POV mesh2{} syntax to exported file """ # obmatslist = [] # def hasUniqueMaterial(): # # Grab materials attached to object instances ... @@ -3318,6 +3353,7 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") def exportWorld(world): + """write world as POV backgrounbd and sky_sphere to exported file """ render = scene.pov camera = scene.camera matrix = global_matrix @ camera.matrix_world @@ -3482,7 +3518,7 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") def exportGlobalSettings(scene): - + """write all POV global settings to exported file """ tabWrite("global_settings {\n") tabWrite("assumed_gamma 1.0\n") tabWrite("max_trace_level %d\n" % scene.pov.max_trace_level) @@ -3570,6 +3606,7 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") def exportCustomCode(): + """write all POV user defined custom code to exported file """ # Write CurrentAnimation Frame for use in Custom POV Code file.write("#declare CURFRAMENUM = %d;\n" % bpy.context.scene.frame_current) #Change path and uncomment to add an animated include file by hand: @@ -3708,6 +3745,7 @@ def write_pov(filename, scene=None, info_callback=None): def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_image): + """Write ini file.""" feature_set = bpy.context.preferences.addons[__package__].preferences.branch_feature_set_povray using_uberpov = (feature_set=='uberpov') #scene = bpy.data.scenes[0] @@ -3782,6 +3820,7 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag class PovrayRender(bpy.types.RenderEngine): + """Define the external renderer""" bl_idname = 'POVRAY_RENDER' bl_label = "Persitence Of Vision" bl_use_shading_nodes_custom = False @@ -3789,6 +3828,7 @@ class PovrayRender(bpy.types.RenderEngine): @staticmethod def _locate_binary(): + """Identify POV engine""" addon_prefs = bpy.context.preferences.addons[__package__].preferences # Use the system preference if its set. @@ -3839,6 +3879,7 @@ class PovrayRender(bpy.types.RenderEngine): return "" def _export(self, depsgraph, povPath, renderImagePath): + """gather all necessary output files paths user defined and auto generated and export there""" import tempfile scene = bpy.context.scene if scene.pov.tempfiles_enable: @@ -3877,6 +3918,7 @@ class PovrayRender(bpy.types.RenderEngine): else: pass def _render(self, depsgraph): + """Export necessary files and render image.""" scene = bpy.context.scene try: os.remove(self._temp_file_out) # so as not to load the old file @@ -3927,6 +3969,7 @@ class PovrayRender(bpy.types.RenderEngine): # Now that we have a valid process def _cleanup(self): + """Delete temp files and unpacked ones""" for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out): for i in range(5): try: @@ -3946,6 +3989,7 @@ class PovrayRender(bpy.types.RenderEngine): # and Windows does not know how to delete a file in use! time.sleep(self.DELAY) def render(self, depsgraph): + """Export necessary files from text editor and render image.""" import tempfile scene = bpy.context.scene r = scene.render @@ -4340,6 +4384,7 @@ class PovrayRender(bpy.types.RenderEngine): #################################Operators######################################## ################################################################################## class RenderPovTexturePreview(Operator): + """Export only files necessary to texture preview and render image.""" bl_idname = "tex.preview_update" bl_label = "Update preview" def execute(self, context): @@ -4432,6 +4477,7 @@ class RenderPovTexturePreview(Operator): return {'FINISHED'} class RunPovTextRender(Operator): + """Export files depending on text editor options and render image.""" bl_idname = "text.run" bl_label = "Run" bl_context = "text" diff --git a/render_povray/shading.py b/render_povray/shading.py index b63443c2..7c229ecb 100644 --- a/render_povray/shading.py +++ b/render_povray/shading.py @@ -1,7 +1,9 @@ -# For BI > POV shaders emulation +"""Translate complex shaders to exported POV textures.""" + import bpy def writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, material): + """Translate Blender material POV texture{} block and write to exported file.""" # Assumes only called once on each material if material: name_orig = material.name @@ -22,6 +24,7 @@ def writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments # Level=3 Means Maximum Spec and Mirror def povHasnoSpecularMaps(Level): + """Translate Blender specular map influence to POV finish map trick and write to file.""" if Level == 1: if comments: tabWrite("//--No specular nor Mirror reflection--\n") @@ -268,6 +271,11 @@ def writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments povHasnoSpecularMaps(Level=3) def exportPattern(texture, string_strip_hyphen): + """Translate Blender procedural textures to POV patterns and write to pov file. + + Function Patterns can be used to better access sub components of a pattern like + grey values for influence mapping""" + tex=texture pat = tex.pov PATname = "PAT_%s"%string_strip_hyphen(bpy.path.clean_name(tex.name)) @@ -752,6 +760,8 @@ def exportPattern(texture, string_strip_hyphen): def writeTextureInfluence(mater, materialNames, LocalMaterialNames, path_image, lampCount, imageFormat, imgMap, imgMapTransforms, tabWrite, comments, string_strip_hyphen, safety, col, os, preview_dir, unpacked_images): + """Translate Blender texture influences to various POV texture tricks and write to pov file.""" + material_finish = materialNames[mater.name] if mater.pov.use_transparency: trans = 1.0 - mater.pov.alpha @@ -1233,6 +1243,7 @@ def string_strip_hyphen(name): return name.replace("-", "") # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! def write_nodes(scene,povMatName,ntree,file): + """translate Blender node trees to pov and write them to file""" declareNodes=[] scene=bpy.context.scene for node in ntree.nodes: diff --git a/render_povray/update_files.py b/render_povray/update_files.py index 2c7beb60..e0d4495d 100644 --- a/render_povray/update_files.py +++ b/render_povray/update_files.py @@ -17,7 +17,10 @@ # ##### END GPL LICENSE BLOCK ##### # <pep8 compliant> +"""update new variables to values from older API. +It does not have a UI and used to be found with F3 search field. +This file needs an update.""" import bpy from bpy.props import ( |