diff --git a/render_povray/__init__.py b/render_povray/__init__.py index a8a5c95152ec854646fd47d168e4e2765dafa18a..8f67892e5a7975153a2c8b985e5d6fb1d4abf6a8 100644 --- a/render_povray/__init__.py +++ b/render_povray/__init__.py @@ -3704,6 +3704,7 @@ class RenderPovSettingsTexture(PropertyGroup): ('PARTICLES', "", "Show particles textures", "PARTICLES",3), # "Show particles textures" ('LINESTYLE', "", "Show linestyle textures", "LINE_DATA",4), # "Show linestyle textures" ('OTHER', "", "Show other data textures", "TEXTURE_DATA",5), # "Show other data textures" + ), default = 'MATERIAL', ) diff --git a/render_povray/primitives.py b/render_povray/primitives.py index 4d10995849683025b38f50365d4256294efbb4ec..a9d68d448c30bc94c80ca19f465386ed709eb622 100644 --- a/render_povray/primitives.py +++ b/render_povray/primitives.py @@ -18,7 +18,7 @@ # <pep8 compliant> -############ To get POV-Ray specific objects In and Out of Blender ########### +""" Get POV-Ray specific objects In and Out of Blender """ import bpy import os.path @@ -29,22 +29,20 @@ from math import atan, pi, degrees, sqrt, cos, sin from bpy.props import ( - StringProperty, - BoolProperty, - IntProperty, - FloatProperty, - FloatVectorProperty, - EnumProperty, - PointerProperty, - CollectionProperty, - ) - -from mathutils import ( - Vector, - Matrix, + StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty, + PointerProperty, + CollectionProperty, ) -#import collections +from mathutils import Vector, Matrix + +# import collections + def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True): """Generate proxy mesh.""" @@ -52,7 +50,9 @@ def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True): mesh = bpy.data.meshes.new(name) mesh.from_pydata(verts, edges, faces) mesh.update() - mesh.validate(verbose = False) # Set it to True to see debug messages (helps ensure you generate valid geometry). + mesh.validate( + verbose=False + ) # Set it to True to see debug messages (helps ensure you generate valid geometry). if hide_geometry: mesh.vertices.foreach_set("hide", [True] * len(mesh.vertices)) mesh.edges.foreach_set("hide", [True] * len(mesh.edges)) @@ -62,26 +62,26 @@ 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'} + bl_options = {'REGISTER', 'UNDO'} bl_description = "adds lathe" - def execute(self, context): - #ayers=[False]*20 - #layers[0]=True + # ayers=[False]*20 + # layers[0]=True bpy.ops.curve.primitive_bezier_curve_add( location=context.scene.cursor.location, rotation=(0, 0, 0), - #layers=layers, + # layers=layers, ) ob = context.view_layer.objects.active ob_data = ob.data ob.name = ob_data.name = "PovLathe" ob_data.dimensions = '2D' ob_data.transform(Matrix.Rotation(-pi / 2.0, 4, 'Z')) - ob.pov.object_as='LATHE' + ob.pov.object_as = 'LATHE' self.report({'INFO'}, "This native POV-Ray primitive") ob.pov.curveshape = "lathe" bpy.ops.object.modifier_add(type='SCREW') @@ -91,7 +91,6 @@ class POVRAY_OT_lathe_add(bpy.types.Operator): return {'FINISHED'} - def pov_superellipsoid_define(context, op, ob): """Create the proxy mesh of a POV superellipsoid using the pov_superellipsoid_define() function.""" @@ -103,11 +102,11 @@ def pov_superellipsoid_define(context, op, ob): n1 = op.se_n1 n2 = op.se_n2 edit = op.se_edit - se_param1 = n2 # op.se_param1 - se_param2 = n1 # op.se_param2 + se_param1 = n2 # op.se_param1 + se_param2 = n1 # op.se_param2 else: - assert(ob) + assert ob mesh = ob.data u = ob.pov.se_u @@ -119,83 +118,85 @@ def pov_superellipsoid_define(context, op, ob): se_param2 = ob.pov.se_param2 verts = [] - r=1 + r = 1 - stepSegment=360/v*pi/180 - stepRing=pi/u - angSegment=0 - angRing=-pi/2 + stepSegment = 360 / v * pi / 180 + stepRing = pi / u + angSegment = 0 + angRing = -pi / 2 - step=0 - for ring in range(0,u-1): + step = 0 + for ring in range(0, u - 1): angRing += stepRing - for segment in range(0,v): + 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 = 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 = 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) + 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)) + 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.append((0, 0, 1)) + verts.append((0, 0, -1)) 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) + 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) + 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) + 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) + 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) + if i == v - 1: + face = (indexUp, i + indexStartDown, indexStartDown) faces.append(face) if edit == 'NGONS': - face=[] - for i in range(0,v): + 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) + 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? + # engine = context.scene.render.engine what for? ob = context.object - ob.name = ob.data.name = "PovSuperellipsoid" + ob.name = ob.data.name = "PovSuperellipsoid" ob.pov.object_as = 'SUPERELLIPSOID' ob.pov.se_param1 = n2 ob.pov.se_param2 = n1 @@ -210,8 +211,10 @@ def pov_superellipsoid_define(context, op, ob): 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" @@ -221,46 +224,68 @@ class POVRAY_OT_superellipsoid_add(bpy.types.Operator): # XXX Keep it in sync with __init__'s RenderPovSettingsConePrimitive # If someone knows how to define operators' props from a func, I'd be delighted to learn it! se_param1: FloatProperty( - name="Parameter 1", - description="", - min=0.00, max=10.0, default=0.04) + name="Parameter 1", description="", min=0.00, max=10.0, default=0.04 + ) se_param2: FloatProperty( - name="Parameter 2", - description="", - min=0.00, max=10.0, default=0.04) - - se_u: IntProperty(name = "U-segments", - description = "radial segmentation", - default = 20, min = 4, max = 265) - se_v: IntProperty(name = "V-segments", - description = "lateral segmentation", - default = 20, min = 4, max = 265) - se_n1: FloatProperty(name = "Ring manipulator", - description = "Manipulates the shape of the Ring", - default = 1.0, min = 0.01, max = 100.0) - se_n2: FloatProperty(name = "Cross manipulator", - description = "Manipulates the shape of the cross-section", - default = 1.0, min = 0.01, max = 100.0) - se_edit: EnumProperty(items=[("NOTHING", "Nothing", ""), - ("NGONS", "N-Gons", ""), - ("TRIANGLES", "Triangles", "")], - name="Fill up and down", - description="", - default='TRIANGLES') + name="Parameter 2", description="", min=0.00, max=10.0, default=0.04 + ) + + se_u: IntProperty( + name="U-segments", + description="radial segmentation", + default=20, + min=4, + max=265, + ) + se_v: IntProperty( + name="V-segments", + description="lateral segmentation", + default=20, + min=4, + max=265, + ) + se_n1: FloatProperty( + name="Ring manipulator", + description="Manipulates the shape of the Ring", + default=1.0, + min=0.01, + max=100.0, + ) + se_n2: FloatProperty( + name="Cross manipulator", + description="Manipulates the shape of the cross-section", + default=1.0, + min=0.01, + max=100.0, + ) + se_edit: EnumProperty( + items=[ + ("NOTHING", "Nothing", ""), + ("NGONS", "N-Gons", ""), + ("TRIANGLES", "Triangles", ""), + ], + name="Fill up and down", + description="", + default='TRIANGLES', + ) @classmethod def poll(cls, context): engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES - def execute(self,context): + def execute(self, context): pov_superellipsoid_define(context, self, None) - self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive won't have any vertex to show in edit mode", + ) return {'FINISHED'} + class POVRAY_OT_superellipsoid_update(bpy.types.Operator): """Update the superellipsoid. @@ -277,7 +302,12 @@ class POVRAY_OT_superellipsoid_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): bpy.ops.object.mode_set(mode="EDIT") @@ -290,6 +320,7 @@ class POVRAY_OT_superellipsoid_update(bpy.types.Operator): return {'FINISHED'} + def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): faces = [] if not vertIdx1 or not vertIdx2: @@ -297,18 +328,15 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): if len(vertIdx1) < 2 and len(vertIdx2) < 2: return None fan = False - if (len(vertIdx1) != len(vertIdx2)): - if (len(vertIdx1) == 1 and len(vertIdx2) > 1): + if len(vertIdx1) != len(vertIdx2): + if len(vertIdx1) == 1 and len(vertIdx2) > 1: fan = True else: return None total = len(vertIdx2) if closed: if flipped: - face = [ - vertIdx1[0], - vertIdx2[0], - vertIdx2[total - 1]] + face = [vertIdx1[0], vertIdx2[0], vertIdx2[total - 1]] if not fan: face.append(vertIdx1[total - 1]) faces.append(face) @@ -324,95 +352,108 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): if fan: face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]] else: - face = [vertIdx2[num], vertIdx1[num], - vertIdx1[num + 1], vertIdx2[num + 1]] + face = [ + vertIdx2[num], + vertIdx1[num], + vertIdx1[num + 1], + vertIdx2[num + 1], + ] faces.append(face) else: if fan: face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]] else: - face = [vertIdx1[num], vertIdx2[num], - vertIdx2[num + 1], vertIdx1[num + 1]] + face = [ + vertIdx1[num], + vertIdx2[num], + vertIdx2[num + 1], + vertIdx1[num + 1], + ] faces.append(face) return faces -def power(a,b): + +def power(a, b): if a < 0: - return -((-a)**b) - return a**b + return -((-a) ** b) + return a ** b -def supertoroid(R,r,u,v,n1,n2): - a = 2*pi/u - b = 2*pi/v + +def supertoroid(R, r, u, v, n1, n2): + a = 2 * pi / u + b = 2 * pi / v verts = [] faces = [] for i in range(u): - s = power(sin(i*a),n1) - c = power(cos(i*a),n1) + s = power(sin(i * a), n1) + c = power(cos(i * a), n1) for j in range(v): - c2 = R+r*power(cos(j*b),n2) - s2 = r*power(sin(j*b),n2) - verts.append((c*c2,s*c2,s2))# type as a (mathutils.Vector(c*c2,s*c2,s2))? + c2 = R + r * power(cos(j * b), n2) + s2 = r * power(sin(j * b), n2) + verts.append( + (c * c2, s * c2, s2) + ) # type as a (mathutils.Vector(c*c2,s*c2,s2))? if i > 0: - f = createFaces(range((i-1)*v,i*v),range(i*v,(i+1)*v),closed = True) + f = createFaces( + range((i - 1) * v, i * v), + range(i * v, (i + 1) * v), + closed=True, + ) faces.extend(f) - f = createFaces(range((u-1)*v,u*v),range(v),closed=True) + f = createFaces(range((u - 1) * v, u * v), range(v), closed=True) faces.extend(f) return verts, faces + def pov_supertorus_define(context, op, ob): - if op: - mesh = None - st_R = op.st_R - st_r = op.st_r - st_u = op.st_u - st_v = op.st_v - st_n1 = op.st_n1 - st_n2 = op.st_n2 - st_ie = op.st_ie - st_edit = op.st_edit + if op: + mesh = None + st_R = op.st_R + st_r = op.st_r + st_u = op.st_u + st_v = op.st_v + st_n1 = op.st_n1 + st_n2 = op.st_n2 + st_ie = op.st_ie + st_edit = op.st_edit + + else: + assert ob + mesh = ob.data + st_R = ob.pov.st_major_radius + st_r = ob.pov.st_minor_radius + st_u = ob.pov.st_u + st_v = ob.pov.st_v + st_n1 = ob.pov.st_ring + st_n2 = ob.pov.st_cross + st_ie = ob.pov.st_ie + st_edit = ob.pov.st_edit + + if st_ie: + rad1 = (st_R + st_r) / 2 + rad2 = (st_R - st_r) / 2 + if rad2 > rad1: + [rad1, rad2] = [rad2, rad1] + else: + rad1 = st_R + rad2 = st_r + if rad2 > rad1: + rad1 = rad2 + verts, faces = supertoroid(rad1, rad2, st_u, st_v, st_n1, st_n2) + mesh = pov_define_mesh(mesh, verts, [], faces, "PovSuperTorus", True) + if not ob: + ob = object_utils.object_data_add(context, mesh, operator=None) + ob.pov.object_as = 'SUPERTORUS' + ob.pov.st_major_radius = st_R + ob.pov.st_minor_radius = st_r + ob.pov.st_u = st_u + ob.pov.st_v = st_v + ob.pov.st_ring = st_n1 + ob.pov.st_cross = st_n2 + ob.pov.st_ie = st_ie + ob.pov.st_edit = st_edit - else: - assert(ob) - mesh = ob.data - st_R = ob.pov.st_major_radius - st_r = ob.pov.st_minor_radius - st_u = ob.pov.st_u - st_v = ob.pov.st_v - st_n1 = ob.pov.st_ring - st_n2 = ob.pov.st_cross - st_ie = ob.pov.st_ie - st_edit = ob.pov.st_edit - - if st_ie: - rad1 = (st_R+st_r)/2 - rad2 = (st_R-st_r)/2 - if rad2 > rad1: - [rad1,rad2] = [rad2,rad1] - else: - rad1 = st_R - rad2 = st_r - if rad2 > rad1: - rad1 = rad2 - verts,faces = supertoroid(rad1, - rad2, - st_u, - st_v, - st_n1, - st_n2) - mesh = pov_define_mesh(mesh, verts, [], faces, "PovSuperTorus", True) - if not ob: - ob = object_utils.object_data_add(context, mesh, operator=None) - ob.pov.object_as = 'SUPERTORUS' - ob.pov.st_major_radius = st_R - ob.pov.st_minor_radius = st_r - ob.pov.st_u = st_u - ob.pov.st_v = st_v - ob.pov.st_ring = st_n1 - ob.pov.st_cross = st_n2 - ob.pov.st_ie = st_ie - 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.""" @@ -423,48 +464,78 @@ class POVRAY_OT_supertorus_add(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} - st_R: FloatProperty(name = "big radius", - description = "The radius inside the tube", - default = 1.0, min = 0.01, max = 100.0) - st_r: FloatProperty(name = "small radius", - description = "The radius of the tube", - default = 0.3, min = 0.01, max = 100.0) - st_u: IntProperty(name = "U-segments", - description = "radial segmentation", - default = 16, min = 3, max = 265) - st_v: IntProperty(name = "V-segments", - description = "lateral segmentation", - default = 8, min = 3, max = 265) - st_n1: FloatProperty(name = "Ring manipulator", - description = "Manipulates the shape of the Ring", - default = 1.0, min = 0.01, max = 100.0) - st_n2: FloatProperty(name = "Cross manipulator", - description = "Manipulates the shape of the cross-section", - default = 1.0, min = 0.01, max = 100.0) - st_ie: BoolProperty(name = "Use Int.+Ext. radii", - description = "Use internal and external radii", - default = False) - st_edit: BoolProperty(name="", - description="", - default=False, - options={'HIDDEN'}) + st_R: FloatProperty( + name="big radius", + description="The radius inside the tube", + default=1.0, + min=0.01, + max=100.0, + ) + st_r: FloatProperty( + name="small radius", + description="The radius of the tube", + default=0.3, + min=0.01, + max=100.0, + ) + st_u: IntProperty( + name="U-segments", + description="radial segmentation", + default=16, + min=3, + max=265, + ) + st_v: IntProperty( + name="V-segments", + description="lateral segmentation", + default=8, + min=3, + max=265, + ) + st_n1: FloatProperty( + name="Ring manipulator", + description="Manipulates the shape of the Ring", + default=1.0, + min=0.01, + max=100.0, + ) + st_n2: FloatProperty( + name="Cross manipulator", + description="Manipulates the shape of the cross-section", + default=1.0, + min=0.01, + max=100.0, + ) + st_ie: BoolProperty( + name="Use Int.+Ext. radii", + description="Use internal and external radii", + default=False, + ) + st_edit: BoolProperty( + name="", description="", default=False, options={'HIDDEN'} + ) @classmethod def poll(cls, context): engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES def execute(self, context): pov_supertorus_define(context, self, None) - self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive won't have any vertex to show in edit mode", + ) 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" @@ -475,7 +546,12 @@ class POVRAY_OT_supertorus_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): bpy.ops.object.mode_set(mode="EDIT") @@ -487,6 +563,8 @@ class POVRAY_OT_supertorus_update(bpy.types.Operator): pov_supertorus_define(context, None, context.object) return {'FINISHED'} + + ######################################################################################################### class POVRAY_OT_loft_add(bpy.types.Operator): """Create the representation of POV loft using Blender curves.""" @@ -497,103 +575,115 @@ class POVRAY_OT_loft_add(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} - loft_n: IntProperty(name = "Segments", - description = "Vertical segments", - default = 16, min = 3, max = 720) - loft_rings_bottom: IntProperty(name = "Bottom", - description = "Bottom rings", - default = 5, min = 2, max = 100) - loft_rings_side: IntProperty(name = "Side", - description = "Side rings", - default = 10, min = 2, max = 100) - loft_thick: FloatProperty(name = "Thickness", - description = "Manipulates the shape of the Ring", - default = 0.3, min = 0.01, max = 1.0) - loft_r: FloatProperty(name = "Radius", - description = "Radius", - default = 1, min = 0.01, max = 10) - loft_height: FloatProperty(name = "Height", - description = "Manipulates the shape of the Ring", - default = 2, min = 0.01, max = 10.0) - - def execute(self,context): + loft_n: IntProperty( + name="Segments", + description="Vertical segments", + default=16, + min=3, + max=720, + ) + loft_rings_bottom: IntProperty( + name="Bottom", description="Bottom rings", default=5, min=2, max=100 + ) + loft_rings_side: IntProperty( + name="Side", description="Side rings", default=10, min=2, max=100 + ) + loft_thick: FloatProperty( + name="Thickness", + description="Manipulates the shape of the Ring", + default=0.3, + min=0.01, + max=1.0, + ) + loft_r: FloatProperty( + name="Radius", description="Radius", default=1, min=0.01, max=10 + ) + loft_height: FloatProperty( + name="Height", + description="Manipulates the shape of the Ring", + default=2, + min=0.01, + max=10.0, + ) + + def execute(self, context): props = self.properties loftData = bpy.data.curves.new('Loft', type='CURVE') loftData.dimensions = '3D' loftData.resolution_u = 2 # loftData.show_normal_face = False # deprecated in 2.8 - n=props.loft_n + n = props.loft_n thick = props.loft_thick side = props.loft_rings_side bottom = props.loft_rings_bottom h = props.loft_height r = props.loft_r - distB = r/bottom + distB = r / bottom r0 = 0.00001 - z = -h/2 + z = -h / 2 print("New") - for i in range(bottom+1): + for i in range(bottom + 1): coords = [] angle = 0 for p in range(n): - x = r0*cos(angle) - y = r0*sin(angle) - coords.append((x,y,z)) - angle+=pi*2/n - r0+=distB + x = r0 * cos(angle) + y = r0 * sin(angle) + coords.append((x, y, z)) + angle += pi * 2 / n + r0 += distB nurbs = loftData.splines.new('NURBS') - nurbs.points.add(len(coords)-1) + nurbs.points.add(len(coords) - 1) for i, coord in enumerate(coords): - x,y,z = coord + x, y, z = coord nurbs.points[i].co = (x, y, z, 1) nurbs.use_cyclic_u = True for i in range(side): - z+=h/side + z += h / side coords = [] angle = 0 for p in range(n): - x = r*cos(angle) - y = r*sin(angle) - coords.append((x,y,z)) - angle+=pi*2/n + x = r * cos(angle) + y = r * sin(angle) + coords.append((x, y, z)) + angle += pi * 2 / n nurbs = loftData.splines.new('NURBS') - nurbs.points.add(len(coords)-1) + nurbs.points.add(len(coords) - 1) for i, coord in enumerate(coords): - x,y,z = coord + x, y, z = coord nurbs.points[i].co = (x, y, z, 1) nurbs.use_cyclic_u = True - r-=thick + r -= thick for i in range(side): coords = [] angle = 0 for p in range(n): - x = r*cos(angle) - y = r*sin(angle) - coords.append((x,y,z)) - angle+=pi*2/n + x = r * cos(angle) + y = r * sin(angle) + coords.append((x, y, z)) + angle += pi * 2 / n nurbs = loftData.splines.new('NURBS') - nurbs.points.add(len(coords)-1) + nurbs.points.add(len(coords) - 1) for i, coord in enumerate(coords): - x,y,z = coord + x, y, z = coord nurbs.points[i].co = (x, y, z, 1) nurbs.use_cyclic_u = True - z-=h/side - z = (-h/2) + thick - distB = (r-0.00001)/bottom - for i in range(bottom+1): + z -= h / side + z = (-h / 2) + thick + distB = (r - 0.00001) / bottom + for i in range(bottom + 1): coords = [] angle = 0 for p in range(n): - x = r*cos(angle) - y = r*sin(angle) - coords.append((x,y,z)) - angle+=pi*2/n - r-=distB + x = r * cos(angle) + y = r * sin(angle) + coords.append((x, y, z)) + angle += pi * 2 / n + r -= distB nurbs = loftData.splines.new('NURBS') - nurbs.points.add(len(coords)-1) + nurbs.points.add(len(coords) - 1) for i, coord in enumerate(coords): - x,y,z = coord + x, y, z = coord nurbs.points[i].co = (x, y, z, 1) nurbs.use_cyclic_u = True ob = bpy.data.objects.new('Loft_shape', loftData) @@ -604,6 +694,7 @@ class POVRAY_OT_loft_add(bpy.types.Operator): ob.pov.curveshape = "loft" return {'FINISHED'} + class POVRAY_OT_plane_add(bpy.types.Operator): """Add the representation of POV infinite plane using just a very big Blender Plane. @@ -615,21 +706,25 @@ class POVRAY_OT_plane_add(bpy.types.Operator): bl_description = "Add Plane" bl_options = {'REGISTER', 'UNDO'} - def execute(self,context): - #layers = 20*[False] - #layers[0] = True - bpy.ops.mesh.primitive_plane_add(size = 100000) + def execute(self, context): + # layers = 20*[False] + # layers[0] = True + bpy.ops.mesh.primitive_plane_add(size=100000) ob = context.object ob.name = ob.data.name = 'PovInfinitePlane' bpy.ops.object.mode_set(mode="EDIT") - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.shade_smooth() ob.pov.object_as = "PLANE" return {'FINISHED'} + class POVRAY_OT_box_add(bpy.types.Operator): """Add the representation of POV box using a simple Blender mesh cube. @@ -641,15 +736,18 @@ class POVRAY_OT_box_add(bpy.types.Operator): bl_description = "Add Box" bl_options = {'REGISTER', 'UNDO'} - def execute(self,context): + def execute(self, context): # layers = 20*[False] # layers[0] = True bpy.ops.mesh.primitive_cube_add() ob = context.object ob.name = ob.data.name = 'PovBox' bpy.ops.object.mode_set(mode="EDIT") - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") ob.pov.object_as = "BOX" @@ -662,11 +760,13 @@ def pov_cylinder_define(context, op, ob, radius, loc, loc_cap): loc = bpy.context.scene.cursor.location loc_cap[0] = loc[0] loc_cap[1] = loc[1] - loc_cap[2] = (loc[2]+2) + loc_cap[2] = loc[2] + 2 vec = Vector(loc_cap) - Vector(loc) depth = vec.length rot = Vector((0, 0, 1)).rotation_difference(vec) # Rotation from Z axis. - trans = rot @ Vector((0, 0, depth / 2)) # Such that origin is at center of the base of the cylinder. + trans = rot @ Vector( + (0, 0, depth / 2) + ) # Such that origin is at center of the base of the cylinder. roteuler = rot.to_euler() if not ob: bpy.ops.object.add(type='MESH', location=loc) @@ -682,7 +782,13 @@ def pov_cylinder_define(context, op, ob, radius, loc, loc_cap): bpy.ops.mesh.reveal() bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.delete(type='VERT') - bpy.ops.mesh.primitive_cylinder_add(radius=radius, depth=depth, location=loc, rotation=roteuler, end_fill_type='NGON') #'NOTHING' + bpy.ops.mesh.primitive_cylinder_add( + radius=radius, + depth=depth, + location=loc, + rotation=roteuler, + end_fill_type='NGON', + ) #'NOTHING' bpy.ops.transform.translate(value=trans) bpy.ops.mesh.hide(unselected=False) @@ -694,6 +800,7 @@ 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" @@ -703,21 +810,19 @@ class POVRAY_OT_cylinder_add(bpy.types.Operator): R: FloatProperty(name="Cylinder radius", min=0.00, max=10.0, default=1.0) imported_cyl_loc: FloatVectorProperty( - name="Imported Pov base location", - precision=6, - default=(0.0, 0.0, 0.0)) + name="Imported Pov base location", precision=6, default=(0.0, 0.0, 0.0) + ) imported_cyl_loc_cap: FloatVectorProperty( - name="Imported Pov cap location", - precision=6, - default=(0.0, 0.0, 2.0)) + name="Imported Pov cap location", precision=6, default=(0.0, 0.0, 2.0) + ) - def execute(self,context): + def execute(self, context): props = self.properties R = props.R ob = context.object - #layers = 20*[False] - #layers[0] = True + # layers = 20*[False] + # layers[0] = True if ob: if ob.pov.imported_cyl_loc: LOC = ob.pov.imported_cyl_loc @@ -730,8 +835,11 @@ class POVRAY_OT_cylinder_add(bpy.types.Operator): else: LOC = props.imported_cyl_loc LOC_CAP = props.imported_cyl_loc_cap - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) pov_cylinder_define(context, self, None, self.R, LOC, LOC_CAP) @@ -754,7 +862,13 @@ class POVRAY_OT_cylinder_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and ob.pov.object_as == "CYLINDER" and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and ob.pov.object_as == "CYLINDER" + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): ob = context.object @@ -778,39 +892,46 @@ def pov_sphere_define(context, op, ob, loc): R = op.R loc = bpy.context.scene.cursor.location else: - assert(ob) + assert ob R = ob.pov.sphere_radius - #keep object rotation and location for the add object operator + # keep object rotation and location for the add object operator obrot = ob.rotation_euler - #obloc = ob.location + # 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.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.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.transform.rotate(axis=obrot,orient_type='GLOBAL') if not ob: - bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=R, location=loc) + bpy.ops.mesh.primitive_ico_sphere_add( + subdivisions=4, radius=R, location=loc + ) ob = context.object - ob.name = ob.data.name = "PovSphere" + 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. @@ -822,20 +943,17 @@ class POVRAY_OT_sphere_add(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} # XXX Keep it in sync with __init__'s torus Primitive - R: FloatProperty(name="Sphere radius",min=0.00, max=10.0, default=0.5) + R: FloatProperty(name="Sphere radius", min=0.00, max=10.0, default=0.5) imported_loc: FloatVectorProperty( - name="Imported Pov location", - precision=6, - default=(0.0, 0.0, 0.0)) + name="Imported Pov location", precision=6, default=(0.0, 0.0, 0.0) + ) - def execute(self,context): + def execute(self, context): props = self.properties R = props.R ob = context.object - - if ob: if ob.pov.imported_loc: LOC = ob.pov.imported_loc @@ -845,27 +963,32 @@ class POVRAY_OT_sphere_add(bpy.types.Operator): else: LOC = props.imported_loc - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) pov_sphere_define(context, self, None, LOC) return {'FINISHED'} # def execute(self,context): - ## layers = 20*[False] - ## layers[0] = True - - # bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius) - # ob = context.object - # bpy.ops.object.mode_set(mode="EDIT") - # self.report({'INFO'}, "This native POV-Ray primitive " - # "won't have any vertex to show in edit mode") - # bpy.ops.mesh.hide(unselected=False) - # bpy.ops.object.mode_set(mode="OBJECT") - # bpy.ops.object.shade_smooth() - # ob.pov.object_as = "SPHERE" - # ob.name = ob.data.name = 'PovSphere' - # return {'FINISHED'} + ## layers = 20*[False] + ## layers[0] = True + + # bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius) + # ob = context.object + # bpy.ops.object.mode_set(mode="EDIT") + # self.report({'INFO'}, "This native POV-Ray primitive " + # "won't have any vertex to show in edit mode") + # bpy.ops.mesh.hide(unselected=False) + # bpy.ops.object.mode_set(mode="OBJECT") + # bpy.ops.object.shade_smooth() + # ob.pov.object_as = "SPHERE" + # ob.name = ob.data.name = 'PovSphere' + # return {'FINISHED'} + + class POVRAY_OT_sphere_update(bpy.types.Operator): """Update the POV sphere. @@ -882,11 +1005,18 @@ class POVRAY_OT_sphere_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): - pov_sphere_define(context, None, context.object,context.object.location) + pov_sphere_define( + context, None, context.object, context.object.location + ) return {'FINISHED'} @@ -905,7 +1035,7 @@ def pov_cone_define(context, op, ob): seg = op.seg height = op.height else: - assert(ob) + assert ob mesh = ob.data base = ob.pov.cone_base_radius cap = ob.pov.cone_cap_radius @@ -966,27 +1096,46 @@ class POVRAY_OT_cone_add(bpy.types.Operator): # 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", - default = 1.0, min = 0.01, max = 100.0) + name="Base radius", + description="The first radius of the cone", + default=1.0, + min=0.01, + max=100.0, + ) cap: FloatProperty( - name = "Cap radius", description = "The second radius of the cone", - default = 0.3, min = 0.0, max = 100.0) + name="Cap radius", + description="The second radius of the cone", + default=0.3, + min=0.0, + max=100.0, + ) seg: IntProperty( - name = "Segments", description = "Radial segmentation of the proxy mesh", - default = 16, min = 3, max = 265) + name="Segments", + description="Radial segmentation of the proxy mesh", + default=16, + min=3, + max=265, + ) height: FloatProperty( - name = "Height", description = "Height of the cone", - default = 2.0, min = 0.01, max = 100.0) + name="Height", + description="Height of the cone", + default=2.0, + min=0.01, + max=100.0, + ) @classmethod def poll(cls, context): engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES def execute(self, context): pov_cone_define(context, self, None) - self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive won't have any vertex to show in edit mode", + ) return {'FINISHED'} @@ -1006,7 +1155,12 @@ class POVRAY_OT_cone_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): bpy.ops.object.mode_set(mode="EDIT") @@ -1019,8 +1173,10 @@ class POVRAY_OT_cone_update(bpy.types.Operator): 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. @@ -1032,15 +1188,17 @@ class POVRAY_OT_isosurface_box_add(bpy.types.Operator): bl_description = "Add Isosurface contained by Box" bl_options = {'REGISTER', 'UNDO'} - - def execute(self,context): - #layers = 20*[False] - #layers[0] = True + def execute(self, context): + # layers = 20*[False] + # layers[0] = True bpy.ops.mesh.primitive_cube_add() ob = context.object bpy.ops.object.mode_set(mode="EDIT") - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") ob.pov.object_as = "ISOSURFACE" @@ -1048,6 +1206,7 @@ class POVRAY_OT_isosurface_box_add(bpy.types.Operator): ob.name = 'PovIsosurfaceBox' return {'FINISHED'} + class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): """Add the representation of POV isosurface sphere by a Blender mesh icosphere. @@ -1059,15 +1218,17 @@ class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): bl_description = "Add Isosurface contained by Sphere" bl_options = {'REGISTER', 'UNDO'} - - def execute(self,context): - #layers = 20*[False] - #layers[0] = True + def execute(self, context): + # layers = 20*[False] + # layers[0] = True bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4) ob = context.object bpy.ops.object.mode_set(mode="EDIT") - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.shade_smooth() @@ -1076,6 +1237,7 @@ class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): ob.name = 'PovIsosurfaceSphere' return {'FINISHED'} + class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): """Add the representation of POV sphere_sweep using a Blender NURBS curve. @@ -1087,9 +1249,9 @@ class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): bl_description = "Create Sphere Sweep along curve" bl_options = {'REGISTER', 'UNDO'} - def execute(self,context): - #layers = 20*[False] - #layers[0] = True + def execute(self, context): + # layers = 20*[False] + # layers[0] = True bpy.ops.curve.primitive_nurbs_curve_add() ob = context.object ob.name = ob.data.name = "PovSphereSweep" @@ -1097,10 +1259,11 @@ class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): ob.data.bevel_depth = 0.02 ob.data.bevel_resolution = 4 ob.data.fill_mode = 'FULL' - #ob.data.splines[0].order_u = 4 + # ob.data.splines[0].order_u = 4 return {'FINISHED'} + class POVRAY_OT_blob_add(bpy.types.Operator): """Add the representation of POV blob using a Blender meta ball. @@ -1112,10 +1275,10 @@ class POVRAY_OT_blob_add(bpy.types.Operator): bl_description = "Add Blob Sphere" bl_options = {'REGISTER', 'UNDO'} - def execute(self,context): - #layers = 20*[False] - #layers[0] = True - bpy.ops.object.metaball_add(type = 'BALL') + def execute(self, context): + # layers = 20*[False] + # layers[0] = True + bpy.ops.object.metaball_add(type='BALL') ob = context.object ob.name = "PovBlob" return {'FINISHED'} @@ -1136,34 +1299,33 @@ class POVRAY_OT_rainbow_add(bpy.types.Operator): bl_description = "Add Rainbow" bl_options = {'REGISTER', 'UNDO'} - def execute(self,context): + def execute(self, context): cam = context.scene.camera bpy.ops.object.light_add(type='SPOT', radius=1) ob = context.object ob.data.show_cone = False ob.data.spot_blend = 0.5 # ob.data.shadow_buffer_clip_end = 0 # deprecated in 2.8 - ob.data.shadow_buffer_clip_start = 4*cam.location.length + ob.data.shadow_buffer_clip_start = 4 * cam.location.length ob.data.distance = cam.location.length ob.data.energy = 0 ob.name = ob.data.name = "PovRainbow" ob.pov.object_as = "RAINBOW" - #obj = context.object + # obj = context.object bpy.ops.object.constraint_add(type='DAMPED_TRACK') - - ob.constraints["Damped Track"].target = cam ob.constraints["Damped Track"].track_axis = 'TRACK_NEGATIVE_Z' ob.location = -cam.location - #refocus on the actual rainbow + # refocus on the actual rainbow bpy.context.view_layer.objects.active = ob ob.select_set(True) return {'FINISHED'} + class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper): """Add the representation of POV height_field using a displaced grid. @@ -1179,68 +1341,67 @@ class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper): # filename_ext = ".png" # filter_glob = StringProperty( - # default="*.exr;*.gif;*.hdr;*.iff;*.jpeg;*.jpg;*.pgm;*.png;*.pot;*.ppm;*.sys;*.tga;*.tiff;*.EXR;*.GIF;*.HDR;*.IFF;*.JPEG;*.JPG;*.PGM;*.PNG;*.POT;*.PPM;*.SYS;*.TGA;*.TIFF", - # options={'HIDDEN'}, - # ) - quality: IntProperty(name = "Quality", - description = "", - default = 100, min = 1, max = 100) - hf_filename: StringProperty(maxlen = 1024) + # default="*.exr;*.gif;*.hdr;*.iff;*.jpeg;*.jpg;*.pgm;*.png;*.pot;*.ppm;*.sys;*.tga;*.tiff;*.EXR;*.GIF;*.HDR;*.IFF;*.JPEG;*.JPG;*.PGM;*.PNG;*.POT;*.PPM;*.SYS;*.TGA;*.TIFF", + # options={'HIDDEN'}, + # ) + quality: IntProperty( + name="Quality", description="", default=100, min=1, max=100 + ) + hf_filename: StringProperty(maxlen=1024) hf_gamma: FloatProperty( - name="Gamma", - description="Gamma", - min=0.0001, max=20.0, default=1.0) + name="Gamma", description="Gamma", min=0.0001, max=20.0, default=1.0 + ) hf_premultiplied: BoolProperty( - name="Premultiplied", - description="Premultiplied", - default=True) + name="Premultiplied", description="Premultiplied", default=True + ) - hf_smooth: BoolProperty( - name="Smooth", - description="Smooth", - default=False) + hf_smooth: BoolProperty(name="Smooth", description="Smooth", default=False) hf_water: FloatProperty( - name="Water Level", - description="Wather Level", - min=0.00, max=1.00, default=0.0) + name="Water Level", + description="Wather Level", + min=0.00, + max=1.00, + default=0.0, + ) hf_hierarchy: BoolProperty( - name="Hierarchy", - description="Height field hierarchy", - default=True) - def execute(self,context): + name="Hierarchy", description="Height field hierarchy", default=True + ) + + def execute(self, context): props = self.properties impath = bpy.path.abspath(self.filepath) img = bpy.data.images.load(impath) im_name = img.name im_name, file_extension = os.path.splitext(im_name) - hf_tex = bpy.data.textures.new('%s_hf_image'%im_name, type = 'IMAGE') + hf_tex = bpy.data.textures.new('%s_hf_image' % im_name, type='IMAGE') hf_tex.image = img - mat = bpy.data.materials.new('Tex_%s_hf'%im_name) + mat = bpy.data.materials.new('Tex_%s_hf' % im_name) hf_slot = mat.pov_texture_slots.add() hf_slot.texture = hf_tex.name - #layers = 20*[False] - #layers[0] = True + # layers = 20*[False] + # layers[0] = True quality = props.quality - res = 100/quality - w,h = hf_tex.image.size[:] - w = int(w/res) - h = int(h/res) - bpy.ops.mesh.primitive_grid_add(x_subdivisions=w, y_subdivisions=h,size = 0.5) + res = 100 / quality + w, h = hf_tex.image.size[:] + w = int(w / res) + h = int(h / res) + bpy.ops.mesh.primitive_grid_add( + x_subdivisions=w, y_subdivisions=h, size=0.5 + ) ob = context.object - ob.name = ob.data.name = '%s'%im_name + ob.name = ob.data.name = '%s' % im_name ob.data.materials.append(mat) bpy.ops.object.mode_set(mode="EDIT") # bpy.ops.mesh.noise(factor=1) # TODO replace by a displace modifier as noise deprecated in 2.8 bpy.ops.object.mode_set(mode="OBJECT") - #needs a loop to select by index? - #bpy.ops.object.material_slot_remove() - #material just left there for now - + # needs a loop to select by index? + # bpy.ops.object.material_slot_remove() + # material just left there for now mat.pov_texture_slots.clear() bpy.ops.object.mode_set(mode="EDIT") @@ -1264,13 +1425,13 @@ def pov_torus_define(context, op, ob): mar = op.mar mir = op.mir else: - assert(ob) + 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 + # keep object rotation and location for the add object operator obrot = ob.rotation_euler obloc = ob.location @@ -1278,17 +1439,27 @@ def pov_torus_define(context, op, ob): 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.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") - if not ob: - bpy.ops.mesh.primitive_torus_add(major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) + 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.name = ob.data.name = "PovTorus" ob.pov.object_as = "TORUS" ob.pov.torus_major_segments = mas ob.pov.torus_minor_segments = mis @@ -1298,6 +1469,7 @@ def pov_torus_define(context, op, ob): 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.""" @@ -1307,27 +1479,27 @@ class POVRAY_OT_torus_add(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} # XXX Keep it in sync with __init__'s torus Primitive - mas: IntProperty(name = "Major Segments", - description = "", - default = 48, min = 3, max = 720) - mis: IntProperty(name = "Minor Segments", - description = "", - default = 12, min = 3, max = 720) - mar: FloatProperty(name = "Major Radius", - description = "", - default = 1.0) - mir: FloatProperty(name = "Minor Radius", - description = "", - default = 0.25) - def execute(self,context): + mas: IntProperty( + name="Major Segments", description="", default=48, min=3, max=720 + ) + mis: IntProperty( + name="Minor Segments", description="", default=12, min=3, max=720 + ) + mar: FloatProperty(name="Major Radius", description="", default=1.0) + mir: FloatProperty(name="Minor Radius", description="", default=0.25) + + def execute(self, context): props = self.properties mar = props.mar mir = props.mir mas = props.mas mis = props.mis pov_torus_define(context, self, None) - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) return {'FINISHED'} @@ -1347,7 +1519,12 @@ class POVRAY_OT_torus_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): @@ -1355,6 +1532,7 @@ class POVRAY_OT_torus_update(bpy.types.Operator): return {'FINISHED'} + ################################################################################### @@ -1366,34 +1544,33 @@ class POVRAY_OT_prism_add(bpy.types.Operator): bl_description = "Create Prism" bl_options = {'REGISTER', 'UNDO'} - prism_n: IntProperty(name = "Sides", - description = "Number of sides", - default = 5, min = 3, max = 720) - prism_r: FloatProperty(name = "Radius", - description = "Radius", - default = 1.0) - def execute(self,context): + prism_n: IntProperty( + name="Sides", description="Number of sides", default=5, min=3, max=720 + ) + prism_r: FloatProperty(name="Radius", description="Radius", default=1.0) + + def execute(self, context): props = self.properties loftData = bpy.data.curves.new('Prism', type='CURVE') loftData.dimensions = '2D' loftData.resolution_u = 2 - #loftData.show_normal_face = False + # loftData.show_normal_face = False loftData.extrude = 2 - n=props.prism_n - r=props.prism_r + n = props.prism_n + r = props.prism_r coords = [] z = 0 angle = 0 for p in range(n): - x = r*cos(angle) - y = r*sin(angle) - coords.append((x,y,z)) - angle+=pi*2/n + x = r * cos(angle) + y = r * sin(angle) + coords.append((x, y, z)) + angle += pi * 2 / n poly = loftData.splines.new('POLY') - poly.points.add(len(coords)-1) + poly.points.add(len(coords) - 1) for i, coord in enumerate(coords): - x,y,z = coord + x, y, z = coord poly.points[i].co = (x, y, z, 1) poly.use_cyclic_u = True @@ -1406,6 +1583,7 @@ class POVRAY_OT_prism_add(bpy.types.Operator): ob.name = ob.data.name = "Prism" return {'FINISHED'} + ##############################PARAMETRIC###################################### def pov_parametric_define(context, op, ob): """Add the representation of POV parametric surfaces by math surface from add mesh extra objects addon.""" @@ -1420,7 +1598,7 @@ def pov_parametric_define(context, op, ob): z_eq = op.z_eq else: - assert(ob) + assert ob u_min = ob.pov.u_min u_max = ob.pov.u_max v_min = ob.pov.v_min @@ -1429,32 +1607,46 @@ def pov_parametric_define(context, op, ob): y_eq = ob.pov.y_eq z_eq = ob.pov.z_eq - #keep object rotation and location for the updated object + # 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 + 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.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) + # 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) + 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.name = ob.data.name = "PovParametric" ob.pov.object_as = "PARAMETRIC" ob.pov.u_min = u_min @@ -1469,6 +1661,7 @@ def pov_parametric_define(context, op, ob): 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.""" @@ -1478,26 +1671,15 @@ class POVRAY_OT_parametric_add(bpy.types.Operator): bl_options = {'REGISTER', 'UNDO'} # XXX Keep it in sync with __init__'s Parametric primitive - u_min: FloatProperty(name = "U Min", - description = "", - default = 0.0) - v_min: FloatProperty(name = "V Min", - description = "", - default = 0.0) - u_max: FloatProperty(name = "U Max", - description = "", - default = 6.28) - v_max: FloatProperty(name = "V Max", - description = "", - default = 12.57) - x_eq: StringProperty( - maxlen=1024, default = "cos(v)*(1+cos(u))*sin(v/8)") - y_eq: StringProperty( - maxlen=1024, default = "sin(u)*sin(v/8)+cos(v/8)*1.5") - z_eq: StringProperty( - maxlen=1024, default = "sin(v)*(1+cos(u))*sin(v/8)") - - def execute(self,context): + u_min: FloatProperty(name="U Min", description="", default=0.0) + v_min: FloatProperty(name="V Min", description="", default=0.0) + u_max: FloatProperty(name="U Max", description="", default=6.28) + v_max: FloatProperty(name="V Max", description="", default=12.57) + x_eq: StringProperty(maxlen=1024, default="cos(v)*(1+cos(u))*sin(v/8)") + y_eq: StringProperty(maxlen=1024, default="sin(u)*sin(v/8)+cos(v/8)*1.5") + z_eq: StringProperty(maxlen=1024, default="sin(v)*(1+cos(u))*sin(v/8)") + + def execute(self, context): props = self.properties u_min = props.u_min v_min = props.v_min @@ -1508,10 +1690,14 @@ class POVRAY_OT_parametric_add(bpy.types.Operator): z_eq = props.z_eq pov_parametric_define(context, self, None) - self.report({'INFO'}, "This native POV-Ray primitive " - "won't have any vertex to show in edit mode") + self.report( + {'INFO'}, + "This native POV-Ray primitive " + "won't have any vertex to show in edit mode", + ) return {'FINISHED'} + class POVRAY_OT_parametric_update(bpy.types.Operator): """Update the representation of POV parametric surfaces. @@ -1528,15 +1714,23 @@ class POVRAY_OT_parametric_update(bpy.types.Operator): def poll(cls, context): engine = context.scene.render.engine ob = context.object - return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES) + return ( + ob + and ob.data + and ob.type == 'MESH' + and engine in cls.COMPAT_ENGINES + ) def execute(self, context): pov_parametric_define(context, None, context.object) return {'FINISHED'} + + ####################################################################### + class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator): """Add the proxy mesh for POV Polygon to circle lofting macro""" @@ -1547,38 +1741,51 @@ class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator): COMPAT_ENGINES = {'POVRAY_RENDER'} # XXX Keep it in sync with __init__'s polytocircle properties - polytocircle_resolution: IntProperty(name = "Resolution", - description = "", - default = 3, min = 0, max = 256) - polytocircle_ngon: IntProperty(name = "NGon", - description = "", - min = 3, max = 64,default = 5) - polytocircle_ngonR: FloatProperty(name = "NGon Radius", - description = "", - default = 0.3) - polytocircle_circleR: FloatProperty(name = "Circle Radius", - description = "", - default = 1.0) - def execute(self,context): + polytocircle_resolution: IntProperty( + name="Resolution", description="", default=3, min=0, max=256 + ) + polytocircle_ngon: IntProperty( + name="NGon", description="", min=3, max=64, default=5 + ) + polytocircle_ngonR: FloatProperty( + name="NGon Radius", description="", default=0.3 + ) + polytocircle_circleR: FloatProperty( + name="Circle Radius", description="", default=1.0 + ) + + def execute(self, context): props = self.properties ngon = props.polytocircle_ngon ngonR = props.polytocircle_ngonR circleR = props.polytocircle_circleR resolution = props.polytocircle_resolution - #layers = 20*[False] - #layers[0] = True - bpy.ops.mesh.primitive_circle_add(vertices=ngon, radius=ngonR, fill_type='NGON',enter_editmode=True) + # layers = 20*[False] + # layers[0] = True + bpy.ops.mesh.primitive_circle_add( + vertices=ngon, radius=ngonR, fill_type='NGON', enter_editmode=True + ) bpy.ops.transform.translate(value=(0, 0, 1)) bpy.ops.mesh.subdivide(number_cuts=resolution) - numCircleVerts = ngon + (ngon*resolution) + numCircleVerts = ngon + (ngon * resolution) bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.mesh.primitive_circle_add(vertices=numCircleVerts, radius=circleR, fill_type='NGON',enter_editmode=True) + bpy.ops.mesh.primitive_circle_add( + vertices=numCircleVerts, + radius=circleR, + fill_type='NGON', + enter_editmode=True, + ) bpy.ops.transform.translate(value=(0, 0, -1)) bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.bridge_edge_loops() if ngon < 5: bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.mesh.primitive_circle_add(vertices=ngon, radius=ngonR, fill_type='TRIFAN',enter_editmode=True) + bpy.ops.mesh.primitive_circle_add( + vertices=ngon, + radius=ngonR, + fill_type='TRIFAN', + enter_editmode=True, + ) bpy.ops.transform.translate(value=(0, 0, 1)) bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.remove_doubles() @@ -1594,10 +1801,13 @@ class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator): bpy.ops.object.mode_set(mode="OBJECT") return {'FINISHED'} + #############################IMPORT + class ImportPOV(bpy.types.Operator, ImportHelper): """Load Povray files""" + bl_idname = "import_scene.pov" bl_label = "POV-Ray files (.pov/.inc)" bl_options = {'PRESET', 'UNDO'} @@ -1605,32 +1815,36 @@ class ImportPOV(bpy.types.Operator, ImportHelper): # ----------- # File props. - files: CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'}) - directory: StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) - - filename_ext = {".pov",".inc"} - filter_glob: StringProperty( - default="*.pov;*.inc", - options={'HIDDEN'}, - ) - - import_at_cur: BoolProperty(name="Import at Cursor Location", - description = "Ignore Object Matrix", - default=False) + files: CollectionProperty( + type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'} + ) + directory: StringProperty( + maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'} + ) + + filename_ext = {".pov", ".inc"} + filter_glob: StringProperty(default="*.pov;*.inc", options={'HIDDEN'}) + + import_at_cur: BoolProperty( + name="Import at Cursor Location", + description="Ignore Object Matrix", + default=False, + ) def execute(self, context): from mathutils import Matrix + verts = [] faces = [] materials = [] - blendMats = [] ############## - povMats = [] ############## + blendMats = [] ############## + povMats = [] ############## colors = [] matNames = [] lenverts = None lenfaces = None suffix = -1 - name = 'Mesh2_%s'%suffix + name = 'Mesh2_%s' % suffix name_search = False verts_search = False faces_search = False @@ -1639,13 +1853,13 @@ class ImportPOV(bpy.types.Operator, ImportHelper): cylinder_search = False sphere_search = False cone_search = False - tex_search = False ################## + tex_search = False ################## cache = [] matrixes = {} writematrix = False index = None value = None - #filepov = bpy.path.abspath(self.filepath) #was used for single files + # filepov = bpy.path.abspath(self.filepath) #was used for single files def mat_search(cache): r = g = b = 0.5 @@ -1659,20 +1873,25 @@ class ImportPOV(bpy.types.Operator, ImportHelper): if value == 'pigment': - if cache[item+2] in {'rgb','srgb'}: + if cache[item + 2] in {'rgb', 'srgb'}: pass - elif cache[item+2] in {'rgbf','srgbf'}: + elif cache[item + 2] in {'rgbf', 'srgbf'}: pass - elif cache[item+2] in {'rgbt','srgbt'}: + elif cache[item + 2] in {'rgbt', 'srgbt'}: try: - r,g,b,t = float(cache[item+3]),float(cache[item+4]),float(cache[item+5]),float(cache[item+6]) + r, g, b, t = ( + float(cache[item + 3]), + float(cache[item + 4]), + float(cache[item + 5]), + float(cache[item + 6]), + ) except: - r = g = b = t = float(cache[item+2]) - color = (r,g,b,t) + r = g = b = t = float(cache[item + 2]) + color = (r, g, b, t) - elif cache[item+2] in {'rgbft','srgbft'}: + elif cache[item + 2] in {'rgbft', 'srgbft'}: pass else: @@ -1680,55 +1899,68 @@ class ImportPOV(bpy.types.Operator, ImportHelper): if colors == [] or (colors != [] and color not in colors): colors.append(color) - name = ob.name+"_mat" + name = ob.name + "_mat" matNames.append(name) mat = bpy.data.materials.new(name) - mat.diffuse_color = (r,g,b) - mat.alpha = 1-t + mat.diffuse_color = (r, g, b) + mat.alpha = 1 - t if mat.alpha != 1: - mat.use_transparency=True + mat.use_transparency = True ob.data.materials.append(mat) else: for i, value in enumerate(colors): if color == value: - ob.data.materials.append(bpy.data.materials[matNames[i]]) + ob.data.materials.append( + bpy.data.materials[matNames[i]] + ) + for file in self.files: - print ("Importing file: "+ file.name) + print("Importing file: " + file.name) filepov = self.directory + file.name for line in open(filepov): - string = line.replace("{"," ") - string = string.replace("}"," ") - string = string.replace("<"," ") - string = string.replace(">"," ") - string = string.replace(","," ") + string = line.replace("{", " ") + string = string.replace("}", " ") + string = string.replace("<", " ") + string = string.replace(">", " ") + string = string.replace(",", " ") lw = string.split() lenwords = len(lw) if lw: if lw[0] == "object": writematrix = True if writematrix: - if lw[0] not in {"object","matrix"}: + if lw[0] not in {"object", "matrix"}: index = lw[0] if lw[0] in {"matrix"}: - value = [float(lw[1]),float(lw[2]),float(lw[3]),\ - float(lw[4]),float(lw[5]),float(lw[6]),\ - float(lw[7]),float(lw[8]),float(lw[9]),\ - float(lw[10]),float(lw[11]),float(lw[12])] - matrixes[index]=value + value = [ + float(lw[1]), + float(lw[2]), + float(lw[3]), + float(lw[4]), + float(lw[5]), + float(lw[6]), + float(lw[7]), + float(lw[8]), + float(lw[9]), + float(lw[10]), + float(lw[11]), + float(lw[12]), + ] + matrixes[index] = value writematrix = False for line in open(filepov): - S = line.replace("{"," { ") - S = S.replace("}"," } ") - S = S.replace(","," ") - S = S.replace("<","") - S = S.replace(">"," ") - S = S.replace("="," = ") - S = S.replace(";"," ; ") + S = line.replace("{", " { ") + S = S.replace("}", " } ") + S = S.replace(",", " ") + S = S.replace("<", "") + S = S.replace(">", " ") + S = S.replace("=", " = ") + S = S.replace(";", " ; ") S = S.split() - lenS= len(S) - for i,word in enumerate(S): - ##################Primitives Import################## + lenS = len(S) + for i, word in enumerate(S): + ##################Primitives Import################## if word == 'cone': cone_search = True name_search = False @@ -1745,10 +1977,12 @@ class ImportPOV(bpy.types.Operator, ImportHelper): z1 = float(cache[8]) r1 = float(cache[9]) # Y is height in most pov files, not z - bpy.ops.pov.cone_add(base=r0, cap=r1, height=(y1-y0)) + bpy.ops.pov.cone_add( + base=r0, cap=r1, height=(y1 - y0) + ) ob = context.object - ob.location = (x0,y0,z0) - #ob.scale = (r,r,r) + ob.location = (x0, y0, z0) + # ob.scale = (r,r,r) mat_search(cache) except (ValueError): pass @@ -1781,9 +2015,13 @@ class ImportPOV(bpy.types.Operator, ImportHelper): x1 = float(cache[5]) y1 = float(cache[6]) z1 = float(cache[7]) - #imported_corner_1=(x0, y0, z0) - #imported_corner_2 =(x1, y1, z1) - center = ((x0 + x1)/2,(y0 + y1)/2,(z0 + z1)/2) + # imported_corner_1=(x0, y0, z0) + # imported_corner_2 =(x1, y1, z1) + center = ( + (x0 + x1) / 2, + (y0 + y1) / 2, + (z0 + z1) / 2, + ) bpy.ops.pov.addbox() ob = context.object ob.location = center @@ -1806,25 +2044,41 @@ class ImportPOV(bpy.types.Operator, ImportHelper): x1 = float(cache[5]) y1 = float(cache[6]) z1 = float(cache[7]) - imported_cyl_loc=(x0, y0, z0) - imported_cyl_loc_cap =(x1, y1, z1) + imported_cyl_loc = (x0, y0, z0) + imported_cyl_loc_cap = (x1, y1, z1) r = float(cache[8]) - - vec = Vector(imported_cyl_loc_cap ) - Vector(imported_cyl_loc) + vec = Vector(imported_cyl_loc_cap) - Vector( + imported_cyl_loc + ) depth = vec.length - rot = Vector((0, 0, 1)).rotation_difference(vec) # Rotation from Z axis. - trans = rot @ Vector((0, 0, depth / 2)) # Such that origin is at center of the base of the cylinder. - #center = ((x0 + x1)/2,(y0 + y1)/2,(z0 + z1)/2) - scaleZ = sqrt((x1-x0)**2+(y1-y0)**2+(z1-z0)**2)/2 - bpy.ops.pov.addcylinder(R=r, imported_cyl_loc=imported_cyl_loc, imported_cyl_loc_cap=imported_cyl_loc_cap) + rot = Vector((0, 0, 1)).rotation_difference( + vec + ) # Rotation from Z axis. + trans = rot @ Vector( + (0, 0, depth / 2) + ) # Such that origin is at center of the base of the cylinder. + # center = ((x0 + x1)/2,(y0 + y1)/2,(z0 + z1)/2) + scaleZ = ( + sqrt( + (x1 - x0) ** 2 + + (y1 - y0) ** 2 + + (z1 - z0) ** 2 + ) + / 2 + ) + bpy.ops.pov.addcylinder( + R=r, + imported_cyl_loc=imported_cyl_loc, + imported_cyl_loc_cap=imported_cyl_loc_cap, + ) ob = context.object ob.location = (x0, y0, z0) ob.rotation_euler = rot.to_euler() - ob.scale = (1,1,scaleZ) + ob.scale = (1, 1, scaleZ) - #scale data rather than obj? + # scale data rather than obj? # bpy.ops.object.mode_set(mode='EDIT') # bpy.ops.mesh.reveal() # bpy.ops.mesh.select_all(action='SELECT') @@ -1858,12 +2112,12 @@ class ImportPOV(bpy.types.Operator, ImportHelper): r = float(cache[3]) bpy.ops.pov.addsphere(R=r, imported_loc=(x, y, z)) ob = context.object - ob.location = (x,y,z) - ob.scale = (r,r,r) + ob.location = (x, y, z) + ob.scale = (r, r, r) mat_search(cache) cache = [] sphere_search = False -##################End Primitives Import################## + ##################End Primitives Import################## if word == '#declare': name_search = True if name_search: @@ -1873,37 +2127,53 @@ class ImportPOV(bpy.types.Operator, ImportHelper): if cache[-2] == '=': name = cache[-3] else: - suffix+=1 + suffix += 1 cache = [] - if word in {'texture',';'}: + if word in {'texture', ';'}: name_search = False cache = [] if word == 'vertex_vectors': - verts_search = True + verts_search = True if verts_search: cache.append(word) if word == '}': verts_search = False - lenverts=cache[2] + lenverts = cache[2] cache.pop() cache.pop(0) cache.pop(0) cache.pop(0) for i in range(int(lenverts)): - x=i*3 - y=(i*3)+1 - z=(i*3)+2 - verts.append((float(cache[x]),float(cache[y]),float(cache[z]))) + x = i * 3 + y = (i * 3) + 1 + z = (i * 3) + 2 + verts.append( + ( + float(cache[x]), + float(cache[y]), + float(cache[z]), + ) + ) cache = [] - #if word == 'face_indices': - #faces_search = True - if word == 'texture_list': ######## - tex_search = True ####### - if tex_search: ######### - if word not in {'texture_list','texture','{','}','face_indices'} and word.isdigit() == False: ############## - povMats.append(word) ################# + # if word == 'face_indices': + # faces_search = True + if word == 'texture_list': ######## + tex_search = True ####### + if tex_search: ######### + if ( + word + not in { + 'texture_list', + 'texture', + '{', + '}', + 'face_indices', + } + and word.isdigit() == False + ): ############## + povMats.append(word) ################# if word == 'face_indices': - tex_search = False ################ + tex_search = False ################ faces_search = True if faces_search: cache.append(word) @@ -1915,61 +2185,101 @@ class ImportPOV(bpy.types.Operator, ImportHelper): cache.pop(0) cache.pop(0) lf = int(lenfaces) - var=int(len(cache)/lf) + var = int(len(cache) / lf) for i in range(lf): if var == 3: - v0=i*3 - v1=i*3+1 - v2=i*3+2 - faces.append((int(cache[v0]),int(cache[v1]),int(cache[v2]))) + v0 = i * 3 + v1 = i * 3 + 1 + v2 = i * 3 + 2 + faces.append( + ( + int(cache[v0]), + int(cache[v1]), + int(cache[v2]), + ) + ) if var == 4: - v0=i*4 - v1=i*4+1 - v2=i*4+2 - m=i*4+3 + v0 = i * 4 + v1 = i * 4 + 1 + v2 = i * 4 + 2 + m = i * 4 + 3 materials.append((int(cache[m]))) - faces.append((int(cache[v0]),int(cache[v1]),int(cache[v2]))) + faces.append( + ( + int(cache[v0]), + int(cache[v1]), + int(cache[v2]), + ) + ) if var == 6: - v0=i*6 - v1=i*6+1 - v2=i*6+2 - m0=i*6+3 - m1=i*6+4 - m2=i*6+5 - materials.append((int(cache[m0]),int(cache[m1]),int(cache[m2]))) - faces.append((int(cache[v0]),int(cache[v1]),int(cache[v2]))) - #mesh = pov_define_mesh(None, verts, [], faces, name, hide_geometry=False) - #ob = object_utils.object_data_add(context, mesh, operator=None) - - me = bpy.data.meshes.new(name) ######## - ob = bpy.data.objects.new(name, me) ########## - bpy.context.collection.objects.link(ob) ######### - me.from_pydata(verts, [], faces) ############ - - for mat in bpy.data.materials: ############## - blendMats.append(mat.name) ############# - for mName in povMats: ##################### - if mName not in blendMats: ########### - povMat = bpy.data.materials.new(mName) ################# + v0 = i * 6 + v1 = i * 6 + 1 + v2 = i * 6 + 2 + m0 = i * 6 + 3 + m1 = i * 6 + 4 + m2 = i * 6 + 5 + materials.append( + ( + int(cache[m0]), + int(cache[m1]), + int(cache[m2]), + ) + ) + faces.append( + ( + int(cache[v0]), + int(cache[v1]), + int(cache[v2]), + ) + ) + # mesh = pov_define_mesh(None, verts, [], faces, name, hide_geometry=False) + # ob = object_utils.object_data_add(context, mesh, operator=None) + + me = bpy.data.meshes.new(name) ######## + ob = bpy.data.objects.new(name, me) ########## + bpy.context.collection.objects.link(ob) ######### + me.from_pydata(verts, [], faces) ############ + + for mat in bpy.data.materials: ############## + blendMats.append(mat.name) ############# + for mName in povMats: ##################### + if mName not in blendMats: ########### + povMat = bpy.data.materials.new( + mName + ) ################# mat_search(cache) - ob.data.materials.append(bpy.data.materials[mName]) ################### - if materials: ################## - for i,val in enumerate(materials): #################### - try: ################### - ob.data.polygons[i].material_index = val #################### - except TypeError: ################### - ob.data.polygons[i].material_index = int(val[0]) ################## - - blendMats = [] ######################### - povMats = [] ######################### - materials = [] ######################### + ob.data.materials.append( + bpy.data.materials[mName] + ) ################### + if materials: ################## + for i, val in enumerate( + materials + ): #################### + try: ################### + ob.data.polygons[ + i + ].material_index = ( + val + ) #################### + except TypeError: ################### + ob.data.polygons[ + i + ].material_index = int( + val[0] + ) ################## + + blendMats = [] ######################### + povMats = [] ######################### + materials = [] ######################### cache = [] name_search = True - if name in matrixes and self.import_at_cur==False: - global_matrix = Matrix.Rotation(pi / 2.0, 4, 'X') + if name in matrixes and self.import_at_cur == False: + global_matrix = Matrix.Rotation( + pi / 2.0, 4, 'X' + ) ob = bpy.context.object - matrix=ob.matrix_world - v=matrixes[name] + matrix = ob.matrix_world + v = matrixes[name] matrix[0][0] = v[0] matrix[1][0] = v[1] matrix[2][0] = v[2] @@ -1982,57 +2292,57 @@ class ImportPOV(bpy.types.Operator, ImportHelper): matrix[0][3] = v[9] matrix[1][3] = v[10] matrix[2][3] = v[11] - matrix = global_matrix*ob.matrix_world + matrix = global_matrix * ob.matrix_world ob.matrix_world = matrix verts = [] faces = [] - # if word == 'pigment': - # try: - # #all indices have been incremented once to fit a bad test file - # r,g,b,t = float(S[2]),float(S[3]),float(S[4]),float(S[5]) - # color = (r,g,b,t) - - # except (IndexError): - # #all indices have been incremented once to fit alternate test file - # r,g,b,t = float(S[3]),float(S[4]),float(S[5]),float(S[6]) - # color = (r,g,b,t) - # except UnboundLocalError: - # # In case no transmit is specified ? put it to 0 - # r,g,b,t = float(S[2]),float(S[3]),float(S[4],0) - # color = (r,g,b,t) - - # except (ValueError): - # color = (0.8,0.8,0.8,0) - # pass - - # if colors == [] or (colors != [] and color not in colors): - # colors.append(color) - # name = ob.name+"_mat" - # matNames.append(name) - # mat = bpy.data.materials.new(name) - # mat.diffuse_color = (r,g,b) - # mat.alpha = 1-t - # if mat.alpha != 1: - # mat.use_transparency=True - # ob.data.materials.append(mat) - # print (colors) - # else: - # for i in range(len(colors)): - # if color == colors[i]: - # ob.data.materials.append(bpy.data.materials[matNames[i]]) + # try: + # #all indices have been incremented once to fit a bad test file + # r,g,b,t = float(S[2]),float(S[3]),float(S[4]),float(S[5]) + # color = (r,g,b,t) + + # except (IndexError): + # #all indices have been incremented once to fit alternate test file + # r,g,b,t = float(S[3]),float(S[4]),float(S[5]),float(S[6]) + # color = (r,g,b,t) + # except UnboundLocalError: + # # In case no transmit is specified ? put it to 0 + # r,g,b,t = float(S[2]),float(S[3]),float(S[4],0) + # color = (r,g,b,t) + + # except (ValueError): + # color = (0.8,0.8,0.8,0) + # pass + + # if colors == [] or (colors != [] and color not in colors): + # colors.append(color) + # name = ob.name+"_mat" + # matNames.append(name) + # mat = bpy.data.materials.new(name) + # mat.diffuse_color = (r,g,b) + # mat.alpha = 1-t + # if mat.alpha != 1: + # mat.use_transparency=True + # ob.data.materials.append(mat) + # print (colors) + # else: + # for i in range(len(colors)): + # if color == colors[i]: + # ob.data.materials.append(bpy.data.materials[matNames[i]]) ##To keep Avogadro Camera angle: # for obj in bpy.context.view_layer.objects: - # if obj.type == "CAMERA": - # track = obj.constraints.new(type = "TRACK_TO") - # track.target = ob - # track.track_axis ="TRACK_NEGATIVE_Z" - # track.up_axis = "UP_Y" - # obj.location = (0,0,0) + # if obj.type == "CAMERA": + # track = obj.constraints.new(type = "TRACK_TO") + # track.target = ob + # track.track_axis ="TRACK_NEGATIVE_Z" + # track.up_axis = "UP_Y" + # obj.location = (0,0,0) return {'FINISHED'} + classes = ( POVRAY_OT_lathe_add, POVRAY_OT_superellipsoid_add, @@ -2065,7 +2375,7 @@ classes = ( def register(): - #from bpy.utils import register_class + # from bpy.utils import register_class for cls in classes: register_class(cls) diff --git a/render_povray/render.py b/render_povray/render.py index 6af0b692d8ad57210c688d18158dcd5c1da87b26..e6c1b01b867929033af7b4cb325a722fa903d055 100644 --- a/render_povray/render.py +++ b/render_povray/render.py @@ -26,17 +26,18 @@ import time from math import atan, pi, degrees, sqrt, cos, sin import re import random -import platform# -import subprocess# -import tempfile #generate temporary files with random names -from bpy.types import(Operator) -from imghdr import what #imghdr is a python lib to identify image file types +import platform # +import subprocess # +import tempfile # generate temporary files with random names +from bpy.types import Operator +from imghdr import what # imghdr is a python lib to identify image file types from bpy.utils import register_class -from . import df3 # for smoke rendering -from . import shading # for BI POV shaders emulation -from . import primitives # for import and export of POV specific primitives -from . import nodes # for POV specific nodes +from . import df3 # for smoke rendering +from . import shading # for BI POV shaders emulation +from . import primitives # for import and export of POV specific primitives +from . import nodes # for POV specific nodes + ##############################SF########################### ##############find image texture def imageFormat(imgF): @@ -58,10 +59,10 @@ def imageFormat(imgF): }.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 + # maybe add a check for if path exists here? + print(" WARNING: texture image has no extension") # too verbose - ext = what(imgF) #imghdr is a python lib to identify image file types + ext = what(imgF) # imghdr is a python lib to identify image file types return ext @@ -77,20 +78,20 @@ def imgMap(ts): ## 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=="?": + # elif ts.mapping=="?": # image_map = " map_type 3 " - #elif ts.mapping=="?": + # elif ts.mapping=="?": # image_map = " map_type 4 " if ts.texture.use_interpolation: image_map += " interpolate 2 " if ts.texture.extension == 'CLIP': image_map += " once " - #image_map += "}" - #if ts.mapping=='CUBE': + # image_map += "}" + # if ts.mapping=='CUBE': # image_map+= "warp { cubic } rotate <-90,0,180>" # no direct cube type mapping. Though this should work in POV 3.7 # it doesn't give that good results(best suited to environment maps?) - #if image_map == "": + # if image_map == "": # print(" No texture image found ") return image_map @@ -102,33 +103,38 @@ def imgMapTransforms(ts): # inverse, a standard scale factor. # 0.5 Offset is needed relatively to scale because center of the # scale is 0.5,0.5 in blender and 0,0 in POV - # Strange that the translation factor for scale is not the same as for - # translate. - # TODO: verify both matches with blender internal. + # Strange that the translation factor for scale is not the same as for + # translate. + # TODO: verify both matches with blender internal. image_map_transforms = "" - image_map_transforms = ("scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" % \ - ( 1.0 / ts.scale.x, - 1.0 / ts.scale.y, - 1.0 / ts.scale.z, - 0.5-(0.5/ts.scale.x) - (ts.offset.x), - 0.5-(0.5/ts.scale.y) - (ts.offset.y), - ts.offset.z)) + image_map_transforms = ( + "scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" + % ( + 1.0 / ts.scale.x, + 1.0 / ts.scale.y, + 1.0 / ts.scale.z, + 0.5 - (0.5 / ts.scale.x) - (ts.offset.x), + 0.5 - (0.5 / ts.scale.y) - (ts.offset.y), + ts.offset.z, + ) + ) # image_map_transforms = (" translate <-0.5,-0.5,0.0> scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" % \ - # ( 1.0 / ts.scale.x, - # 1.0 / ts.scale.y, - # 1.0 / ts.scale.z, - # (0.5 / ts.scale.x) + ts.offset.x, - # (0.5 / ts.scale.y) + ts.offset.y, - # ts.offset.z)) + # ( 1.0 / ts.scale.x, + # 1.0 / ts.scale.y, + # 1.0 / ts.scale.z, + # (0.5 / ts.scale.x) + ts.offset.x, + # (0.5 / ts.scale.y) + ts.offset.y, + # ts.offset.z)) # image_map_transforms = ("translate <-0.5,-0.5,0> scale <-1,-1,1> * <%.4g,%.4g,%.4g> translate <0.5,0.5,0> + <%.4g,%.4g,%.4g>" % \ - # (1.0 / ts.scale.x, - # 1.0 / ts.scale.y, - # 1.0 / ts.scale.z, - # ts.offset.x, - # ts.offset.y, - # ts.offset.z)) + # (1.0 / ts.scale.x, + # 1.0 / ts.scale.y, + # 1.0 / ts.scale.z, + # ts.offset.x, + # ts.offset.y, + # ts.offset.z)) return image_map_transforms + def imgMapBG(wts): """Translate world mapping from Blender UI to POV syntax and return that string.""" image_mapBG = "" @@ -144,21 +150,25 @@ def imgMapBG(wts): image_mapBG += " interpolate 2 " if wts.texture.extension == 'CLIP': image_mapBG += " once " - #image_mapBG += "}" - #if wts.mapping == 'CUBE': + # image_mapBG += "}" + # if wts.mapping == 'CUBE': # image_mapBG += "warp { cubic } rotate <-90,0,180>" # no direct cube type mapping. Though this should work in POV 3.7 # it doesn't give that good results(best suited to environment maps?) - #if image_mapBG == "": + # if image_mapBG == "": # print(" No background texture image found ") return image_mapBG 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("\\","/") + 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 + + # end find image texture # ----------------------------------------------------------------------------- @@ -203,18 +213,21 @@ def safety(name, Level): csg_list = [] + def is_renderable(scene, ob): - return (not ob.hide_render and ob not in csg_list) + return not ob.hide_render and ob not in csg_list def renderable_objects(scene): return [ob for ob in bpy.data.objects if is_renderable(scene, ob)] + def no_renderable_objects(scene): return [ob for ob in csg_list] + tabLevel = 0 -unpacked_images=[] +unpacked_images = [] user_dir = bpy.utils.resource_path('USER') preview_dir = os.path.join(user_dir, "preview") @@ -306,7 +319,9 @@ def write_global_setting(scene,file): file.write("}\n") file.write("}\n") ''' -def write_object_modifiers(scene,ob,File): + + +def write_object_modifiers(scene, ob, File): """Translate some object level POV statements from Blender UI to POV syntax and write to exported file """ @@ -369,11 +384,11 @@ 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 = filename file = open(filename, "w") # Only for testing @@ -384,9 +399,13 @@ def write_pov(filename, scene=None, info_callback=None): world = scene.world 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 - feature_set = bpy.context.preferences.addons[__package__].preferences.branch_feature_set_povray - using_uberpov = (feature_set=='uberpov') + linebreaksinlists = ( + scene.pov.list_lf_enable and not scene.pov.tempfiles_enable + ) + feature_set = bpy.context.preferences.addons[ + __package__ + ].preferences.branch_feature_set_povray + using_uberpov = feature_set == 'uberpov' pov_binary = PovrayRender._locate_binary() if using_uberpov: @@ -394,9 +413,14 @@ def write_pov(filename, scene=None, info_callback=None): else: print("Official POV-Ray 3.7 feature set chosen in preferences") if 'uber' in pov_binary: - print("The name of the binary suggests you are probably rendering with Uber POV engine") + print( + "The name of the binary suggests you are probably rendering with Uber POV engine" + ) else: - print("The name of the binary suggests you are probably rendering with standard POV engine") + print( + "The name of the binary suggests you are probably rendering with standard POV engine" + ) + def setTab(tabtype, spaces): TabStr = "" if tabtype == 'NONE': @@ -409,10 +433,16 @@ 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("]") + brackets = ( + str_o.count("{") + - str_o.count("}") + + str_o.count("[") + - str_o.count("]") + ) if brackets < 0: tabLevel = tabLevel + brackets if tabLevel < 0: @@ -423,7 +453,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(str_o) if brackets > 0: tabLevel = tabLevel + brackets + else: + def tabWrite(str_o): """write directly to exported file if user checked autonamed temp files (faster).""" @@ -447,20 +479,44 @@ def write_pov(filename, scene=None, info_callback=None): 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], - matrix[0][2], matrix[1][2], matrix[2][2], - matrix[0][3], matrix[1][3], matrix[2][3])) + 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], + matrix[0][2], + matrix[1][2], + matrix[2][2], + 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], - matrix[0][2], matrix[1][2], matrix[2][2], - matrix[0][3], matrix[1][3], matrix[2][3])) + 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], + matrix[0][2], + matrix[1][2], + matrix[2][2], + matrix[0][3], + matrix[1][3], + matrix[2][3], + ) + ) return sMatrix def writeObjectMaterial(material, ob): @@ -471,10 +527,12 @@ def write_pov(filename, scene=None, info_callback=None): # this should be checked to see if it is functionally correct # Commented out: always write IOR to be able to use it for SSS, Fresnel reflections... - #if material and material.transparency_method == 'RAYTRACE': + # if material and material.transparency_method == 'RAYTRACE': if material: # But there can be only one! - if material.pov_subsurface_scattering.use: # SSS IOR get highest priority + if ( + material.pov_subsurface_scattering.use + ): # SSS IOR get highest priority tabWrite("interior {\n") tabWrite("ior %.6f\n" % material.pov_subsurface_scattering.ior) # Then the raytrace IOR taken from raytrace transparency properties and used for @@ -482,7 +540,7 @@ def write_pov(filename, scene=None, info_callback=None): elif material.pov.mirror_use_IOR: tabWrite("interior {\n") tabWrite("ior %.6f\n" % material.pov_raytrace_transparency.ior) - elif material.pov.transparency_method=='Z_TRANSPARENCY': + elif material.pov.transparency_method == 'Z_TRANSPARENCY': tabWrite("interior {\n") tabWrite("ior 1.0\n") else: @@ -511,28 +569,49 @@ def write_pov(filename, scene=None, info_callback=None): # reflections in raytrace mirror parameters. And pov IOR defaults to 1. if material.pov.caustics_enable: if pov_fake_caustics: - tabWrite("caustics %.3g\n" % material.pov.fake_caustics_power) + tabWrite( + "caustics %.3g\n" % material.pov.fake_caustics_power + ) if pov_photons_refraction: # Default of 1 means no dispersion - tabWrite("dispersion %.6f\n" % material.pov.photons_dispersion) - tabWrite("dispersion_samples %.d\n" % material.pov.photons_dispersion_samples) - #TODO + tabWrite( + "dispersion %.6f\n" % material.pov.photons_dispersion + ) + tabWrite( + "dispersion_samples %.d\n" + % material.pov.photons_dispersion_samples + ) + # TODO # Other interior args - if material.pov.use_transparency and material.pov.transparency_method == 'RAYTRACE': + if ( + material.pov.use_transparency + and material.pov.transparency_method == 'RAYTRACE' + ): # fade_distance # In Blender this value has always been reversed compared to what tooltip says. # 100.001 rather than 100 so that it does not get to 0 # which deactivates the feature in POV - tabWrite("fade_distance %.3g\n" % \ - (100.001 - material.pov_raytrace_transparency.depth_max)) + tabWrite( + "fade_distance %.3g\n" + % (100.001 - material.pov_raytrace_transparency.depth_max) + ) # fade_power - tabWrite("fade_power %.3g\n" % material.pov_raytrace_transparency.falloff) + tabWrite( + "fade_power %.3g\n" + % material.pov_raytrace_transparency.falloff + ) # fade_color - tabWrite("fade_color <%.3g, %.3g, %.3g>\n" % material.pov.interior_fade_color[:]) + tabWrite( + "fade_color <%.3g, %.3g, %.3g>\n" + % material.pov.interior_fade_color[:] + ) # (variable) dispersion_samples (constant count for now) tabWrite("}\n") - if material.pov.photons_reflection or material.pov.refraction_type=="2": + if ( + material.pov.photons_reflection + or material.pov.refraction_type == "2" + ): tabWrite("photons{") tabWrite("target %.3g\n" % ob.pov.spacing_multiplier) if not ob.pov.collect_photons: @@ -544,27 +623,39 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") materialNames = {} - DEF_MAT_NAME = "" #or "Default"? + 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 - active_object = None # bpy.context.active_object # does not always work MR + active_object = ( + None + ) # bpy.context.active_object # does not always work MR matrix = global_matrix @ camera.matrix_world focal_point = camera.data.dof.focus_distance # compute resolution Qsize = render.resolution_x / render.resolution_y - tabWrite("#declare camLocation = <%.6f, %.6f, %.6f>;\n" % - matrix.translation[:]) - tabWrite("#declare camLookAt = <%.6f, %.6f, %.6f>;\n" % - tuple([degrees(e) for e in matrix.to_3x3().to_euler()])) + tabWrite( + "#declare camLocation = <%.6f, %.6f, %.6f>;\n" + % matrix.translation[:] + ) + tabWrite( + "#declare camLookAt = <%.6f, %.6f, %.6f>;\n" + % tuple([degrees(e) for e in matrix.to_3x3().to_euler()]) + ) tabWrite("camera {\n") - if scene.pov.baking_enable and active_object and active_object.type == 'MESH': - tabWrite("mesh_camera{ 1 3\n") # distribution 3 is what we want here + if ( + scene.pov.baking_enable + and active_object + and active_object.type == 'MESH' + ): + tabWrite( + "mesh_camera{ 1 3\n" + ) # distribution 3 is what we want here tabWrite("mesh{%s}\n" % active_object.name) tabWrite("}\n") tabWrite("location <0,0,.01>") @@ -573,35 +664,54 @@ def write_pov(filename, scene=None, info_callback=None): else: tabWrite("location <0, 0, 0>\n") tabWrite("look_at <0, 0, -1>\n") - tabWrite("right <%s, 0, 0>\n" % - Qsize) + tabWrite("right <%s, 0, 0>\n" % -Qsize) tabWrite("up <0, 1, 0>\n") - tabWrite("angle %f\n" % (360.0 * atan(16.0 / camera.data.lens) / pi)) - - tabWrite("rotate <%.6f, %.6f, %.6f>\n" % \ - tuple([degrees(e) for e in matrix.to_3x3().to_euler()])) + tabWrite( + "angle %f\n" % (360.0 * atan(16.0 / camera.data.lens) / pi) + ) + + tabWrite( + "rotate <%.6f, %.6f, %.6f>\n" + % tuple([degrees(e) for e in matrix.to_3x3().to_euler()]) + ) tabWrite("translate <%.6f, %.6f, %.6f>\n" % matrix.translation[:]) - if camera.data.dof.use_dof and (focal_point != 0 or camera.data.dof.focus_object): - tabWrite("aperture %.3g\n" % (1/camera.data.dof.aperture_fstop*1000)) - tabWrite("blur_samples %d %d\n" % \ - (camera.data.pov.dof_samples_min, camera.data.pov.dof_samples_max)) + if camera.data.dof.use_dof and ( + focal_point != 0 or camera.data.dof.focus_object + ): + tabWrite( + "aperture %.3g\n" + % (1 / camera.data.dof.aperture_fstop * 1000) + ) + tabWrite( + "blur_samples %d %d\n" + % ( + camera.data.pov.dof_samples_min, + camera.data.pov.dof_samples_max, + ) + ) tabWrite("variance 1/%d\n" % camera.data.pov.dof_variance) tabWrite("confidence %.3g\n" % camera.data.pov.dof_confidence) if camera.data.dof.focus_object: focalOb = scene.objects[camera.data.dof.focus_object.name] matrixBlur = global_matrix @ focalOb.matrix_world - tabWrite("focal_point <%.4f,%.4f,%.4f>\n"% matrixBlur.translation[:]) + tabWrite( + "focal_point <%.4f,%.4f,%.4f>\n" + % matrixBlur.translation[:] + ) else: tabWrite("focal_point <0, 0, %f>\n" % focal_point) if camera.data.pov.normal_enable: - tabWrite("normal {%s %.4f turbulence %.4f scale %.4f}\n"% - (camera.data.pov.normal_patterns, + tabWrite( + "normal {%s %.4f turbulence %.4f scale %.4f}\n" + % ( + camera.data.pov.normal_patterns, camera.data.pov.cam_normal, camera.data.pov.turbulence, - camera.data.pov.scale)) + camera.data.pov.scale, + ) + ) tabWrite("}\n") - - 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 @@ -627,9 +737,16 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("spotlight\n") # Falloff is the main radius from the centre line - tabWrite("falloff %.2f\n" % (degrees(lamp.spot_size) / 2.0)) # 1 TO 179 FOR BOTH - tabWrite("radius %.6f\n" % \ - ((degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend))) + tabWrite( + "falloff %.2f\n" % (degrees(lamp.spot_size) / 2.0) + ) # 1 TO 179 FOR BOTH + tabWrite( + "radius %.6f\n" + % ( + (degrees(lamp.spot_size) / 2.0) + * (1.0 - lamp.spot_blend) + ) + ) # Blender does not have a tightness equivalent, 0 is most like blender default. tabWrite("tightness 0\n") # 0:10f @@ -637,11 +754,14 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("point_at <0, 0, -1>\n") if lamp.pov.use_halo: tabWrite("looks_like{\n") - tabWrite("sphere{<0,0,0>,%.6f\n" %lamp.distance) + tabWrite("sphere{<0,0,0>,%.6f\n" % lamp.distance) tabWrite("hollow\n") tabWrite("material{\n") tabWrite("texture{\n") - tabWrite("pigment{rgbf<1,1,1,%.4f>}\n" % (lamp.pov.halo_intensity*5.0)) + tabWrite( + "pigment{rgbf<1,1,1,%.4f>}\n" + % (lamp.pov.halo_intensity * 5.0) + ) tabWrite("}\n") tabWrite("interior{\n") tabWrite("media{\n") @@ -678,8 +798,10 @@ def write_pov(filename, scene=None, info_callback=None): size_y = lamp.size_y samples_y = lamp.pov.shadow_ray_samples_y - tabWrite("area_light <%.6f,0,0>,<0,%.6f,0> %d, %d\n" % \ - (size_x, size_y, samples_x, samples_y)) + tabWrite( + "area_light <%.6f,0,0>,<0,%.6f,0> %d, %d\n" + % (size_x, size_y, samples_x, samples_y) + ) tabWrite("area_illumination\n") if lamp.pov.shadow_ray_sample_method == 'CONSTANT_JITTERED': if lamp.pov.use_jitter: @@ -689,16 +811,21 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("jitter\n") # No shadow checked either at global or light level: - if(not scene.pov.use_shadows or - (lamp.pov.shadow_method == 'NOSHADOW')): + if not scene.pov.use_shadows or ( + lamp.pov.shadow_method == 'NOSHADOW' + ): tabWrite("shadowless\n") # Sun shouldn't be attenuated. Area lights have no falloff attribute so they # are put to type 2 attenuation a little higher above. if lamp.type not in {'SUN', 'AREA'}: if lamp.falloff_type == 'INVERSE_SQUARE': - tabWrite("fade_distance %.6f\n" % (sqrt(lamp.distance/2.0))) - tabWrite("fade_power %d\n" % 2) # Use blenders lamp quad equivalent + tabWrite( + "fade_distance %.6f\n" % (sqrt(lamp.distance / 2.0)) + ) + tabWrite( + "fade_power %d\n" % 2 + ) # Use blenders lamp quad equivalent elif lamp.falloff_type == 'INVERSE_LINEAR': tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0)) tabWrite("fade_power %d\n" % 1) # Use blenders lamp linear @@ -717,56 +844,68 @@ def write_pov(filename, scene=None, info_callback=None): lampCount += 1 # v(A,B) rotates vector A about origin by vector B. - file.write("#declare lampTarget%s= vrotate(<%.4g,%.4g,%.4g>,<%.4g,%.4g,%.4g>);\n" % \ - (lampCount, -(ob.location.x), -(ob.location.y), -(ob.location.z), - ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z)) - -#################################################################################################### + file.write( + "#declare lampTarget%s= vrotate(<%.4g,%.4g,%.4g>,<%.4g,%.4g,%.4g>);\n" + % ( + lampCount, + -(ob.location.x), + -(ob.location.y), + -(ob.location.z), + ob.rotation_euler.x, + ob.rotation_euler.y, + ob.rotation_euler.z, + ) + ) + + #################################################################################################### 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 - width = ob.data.spot_blend *10 + povdataname = ob.data.name # enough? + angle = degrees(ob.data.spot_size / 2.5) # radians in blender (2 + width = ob.data.spot_blend * 10 distance = ob.data.shadow_buffer_clip_start - #eps=0.0000001 - #angle = br/(cr+eps) * 10 #eps is small epsilon variable to avoid dividing by zero - #width = ob.dimensions[2] #now let's say width of rainbow is the actual proxy height + # eps=0.0000001 + # angle = br/(cr+eps) * 10 #eps is small epsilon variable to avoid dividing by zero + # width = ob.dimensions[2] #now let's say width of rainbow is the actual proxy height # formerly: - #cz-bz # let's say width of the rainbow is height of the cone (interfacing choice + # cz-bz # let's say width of the rainbow is height of the cone (interfacing choice # v(A,B) rotates vector A about origin by vector B. # and avoid a 0 length vector by adding 1 # file.write("#declare %s_Target= vrotate(<%.6g,%.6g,%.6g>,<%.4g,%.4g,%.4g>);\n" % \ - # (povdataname, -(ob.location.x+0.1), -(ob.location.y+0.1), -(ob.location.z+0.1), - # ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z)) - - direction = (ob.location.x,ob.location.y,ob.location.z) # not taking matrix into account + # (povdataname, -(ob.location.x+0.1), -(ob.location.y+0.1), -(ob.location.z+0.1), + # ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z)) + + direction = ( + ob.location.x, + ob.location.y, + ob.location.z, + ) # not taking matrix into account rmatrix = global_matrix @ ob.matrix_world - #ob.rotation_euler.to_matrix().to_4x4() * mathutils.Vector((0,0,1)) + # ob.rotation_euler.to_matrix().to_4x4() * mathutils.Vector((0,0,1)) # XXX Is result of the below offset by 90 degrees? - up =ob.matrix_world.to_3x3()[1].xyz #* global_matrix - + up = ob.matrix_world.to_3x3()[1].xyz # * global_matrix # XXX TO CHANGE: - #formerly: - #tabWrite("#declare %s = rainbow {\n"%povdataname) + # formerly: + # tabWrite("#declare %s = rainbow {\n"%povdataname) # clumsy for now but remove the rainbow from instancing # system because not an object. use lamps later instead of meshes - #del data_ref[dataname] + # del data_ref[dataname] tabWrite("rainbow {\n") - tabWrite("angle %.4f\n"%angle) - tabWrite("width %.4f\n"%width) - tabWrite("distance %.4f\n"%distance) - tabWrite("arc_angle %.4f\n"%ob.pov.arc_angle) - tabWrite("falloff_angle %.4f\n"%ob.pov.falloff_angle) - tabWrite("direction <%.4f,%.4f,%.4f>\n"%rmatrix.translation[:]) - tabWrite("up <%.4f,%.4f,%.4f>\n"%(up[0],up[1],up[2])) + tabWrite("angle %.4f\n" % angle) + tabWrite("width %.4f\n" % width) + tabWrite("distance %.4f\n" % distance) + tabWrite("arc_angle %.4f\n" % ob.pov.arc_angle) + tabWrite("falloff_angle %.4f\n" % ob.pov.falloff_angle) + tabWrite("direction <%.4f,%.4f,%.4f>\n" % rmatrix.translation[:]) + tabWrite("up <%.4f,%.4f,%.4f>\n" % (up[0], up[1], up[2])) tabWrite("color_map {\n") tabWrite("[0.000 color srgbt<1.0, 0.5, 1.0, 1.0>]\n") tabWrite("[0.130 color srgbt<0.5, 0.5, 1.0, 0.9>]\n") @@ -779,17 +918,16 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("[1.000 color srgbt<1.0, 0.2, 0.2, 1.0>]\n") tabWrite("}\n") - povMatName = "Default_texture" - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") - #matrix = global_matrix @ ob.matrix_world - #writeMatrix(matrix) + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") + # matrix = global_matrix @ ob.matrix_world + # writeMatrix(matrix) tabWrite("}\n") - #continue #Don't render proxy mesh, skip to next object + # continue #Don't render proxy mesh, skip to next object -################################XXX LOFT, ETC. + ################################XXX LOFT, ETC. def exportCurves(scene, ob): """write all curves based POV primitives to exported file """ name_orig = "OB" + ob.name @@ -802,29 +940,43 @@ def write_pov(filename, scene=None, info_callback=None): matrix = global_matrix @ ob.matrix_world bezier_sweep = False if ob.pov.curveshape == 'sphere_sweep': - #inlined spheresweep macro, which itself calls Shapes.inc: + # inlined spheresweep macro, which itself calls Shapes.inc: file.write(' #include "shapes.inc"\n') - file.write(' #macro Shape_Bezierpoints_Sphere_Sweep(_merge_shape, _resolution, _points_array, _radius_array)\n') + file.write( + ' #macro Shape_Bezierpoints_Sphere_Sweep(_merge_shape, _resolution, _points_array, _radius_array)\n' + ) file.write(' //input adjusting and inspection\n') file.write(' #if(_resolution <= 1)\n') file.write(' #local res = 1;\n') file.write(' #else\n') file.write(' #local res = int(_resolution);\n') file.write(' #end\n') - file.write(' #if(dimensions(_points_array) != 1 | dimensions(_radius_array) != 1)\n') + file.write( + ' #if(dimensions(_points_array) != 1 | dimensions(_radius_array) != 1)\n' + ) file.write(' #error ""\n') - file.write(' #elseif(div(dimension_size(_points_array,1),4) - dimension_size(_points_array,1)/4 != 0)\n') + file.write( + ' #elseif(div(dimension_size(_points_array,1),4) - dimension_size(_points_array,1)/4 != 0)\n' + ) file.write(' #error ""\n') - file.write(' #elseif(dimension_size(_points_array,1) != dimension_size(_radius_array,1))\n') + file.write( + ' #elseif(dimension_size(_points_array,1) != dimension_size(_radius_array,1))\n' + ) file.write(' #error ""\n') file.write(' #else\n') - file.write(' #local n_of_seg = div(dimension_size(_points_array,1), 4);\n') + file.write( + ' #local n_of_seg = div(dimension_size(_points_array,1), 4);\n' + ) file.write(' #local ctrl_pts_array = array[n_of_seg]\n') file.write(' #local ctrl_rs_array = array[n_of_seg]\n') file.write(' #for(i, 0, n_of_seg-1)\n') - file.write(' #local ctrl_pts_array[i] = array[4] {_points_array[4*i], _points_array[4*i+1], _points_array[4*i+2], _points_array[4*i+3]}\n') - file.write(' #local ctrl_rs_array[i] = array[4] {abs(_radius_array[4*i]), abs(_radius_array[4*i+1]), abs(_radius_array[4*i+2]), abs(_radius_array[4*i+3])}\n') + file.write( + ' #local ctrl_pts_array[i] = array[4] {_points_array[4*i], _points_array[4*i+1], _points_array[4*i+2], _points_array[4*i+3]}\n' + ) + file.write( + ' #local ctrl_rs_array[i] = array[4] {abs(_radius_array[4*i]), abs(_radius_array[4*i+1]), abs(_radius_array[4*i+2]), abs(_radius_array[4*i+3])}\n' + ) file.write(' #end\n') file.write(' #end\n') @@ -834,25 +986,39 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #for(i, 0, n_of_seg-1)\n') file.write(' #local has_head = true;\n') file.write(' #if(i = 0)\n') - file.write(' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[n_of_seg-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[n_of_seg-1][3] <= 0)\n') + file.write( + ' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[n_of_seg-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[n_of_seg-1][3] <= 0)\n' + ) file.write(' #local has_head = false;\n') file.write(' #end\n') file.write(' #else\n') - file.write(' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[i-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[i-1][3] <= 0)\n') + file.write( + ' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[i-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[i-1][3] <= 0)\n' + ) file.write(' #local has_head = false;\n') file.write(' #end\n') file.write(' #end\n') file.write(' #if(has_head = true)\n') file.write(' sphere{\n') - file.write(' ctrl_pts_array[i][0], ctrl_rs_array[i][0]\n') + file.write( + ' ctrl_pts_array[i][0], ctrl_rs_array[i][0]\n' + ) file.write(' }\n') file.write(' #end\n') file.write(' #local para_t = (1/2)/res;\n') - file.write(' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n') - file.write(' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n') - file.write(' #if(vlength(this_point-ctrl_pts_array[i][0]) > abs(this_radius-ctrl_rs_array[i][0]))\n') + file.write( + ' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n' + ) + file.write( + ' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n' + ) + file.write( + ' #if(vlength(this_point-ctrl_pts_array[i][0]) > abs(this_radius-ctrl_rs_array[i][0]))\n' + ) file.write(' object{\n') - file.write(' Connect_Spheres(ctrl_pts_array[i][0], ctrl_rs_array[i][0], this_point, this_radius)\n') + file.write( + ' Connect_Spheres(ctrl_pts_array[i][0], ctrl_rs_array[i][0], this_point, this_radius)\n' + ) file.write(' }\n') file.write(' #end\n') file.write(' sphere{\n') @@ -860,13 +1026,23 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' }\n') file.write(' #for(j, 1, res-1)\n') file.write(' #local last_point = this_point;\n') - file.write(' #local last_radius = this_radius;\n') + file.write( + ' #local last_radius = this_radius;\n' + ) file.write(' #local para_t = (1/2+j)/res;\n') - file.write(' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n') - file.write(' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n') - file.write(' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n') + file.write( + ' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n' + ) + file.write( + ' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n' + ) + file.write( + ' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n' + ) file.write(' object{\n') - file.write(' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n') + file.write( + ' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n' + ) file.write(' }\n') file.write(' #end\n') file.write(' sphere{\n') @@ -875,11 +1051,19 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #end\n') file.write(' #local last_point = this_point;\n') file.write(' #local last_radius = this_radius;\n') - file.write(' #local this_point = ctrl_pts_array[i][3];\n') - file.write(' #local this_radius = ctrl_rs_array[i][3];\n') - file.write(' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n') + file.write( + ' #local this_point = ctrl_pts_array[i][3];\n' + ) + file.write( + ' #local this_radius = ctrl_rs_array[i][3];\n' + ) + file.write( + ' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n' + ) file.write(' object{\n') - file.write(' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n') + file.write( + ' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n' + ) file.write(' }\n') file.write(' #end\n') file.write(' sphere{\n') @@ -893,37 +1077,37 @@ def write_pov(filename, scene=None, info_callback=None): for spl in ob.data.splines: if spl.type == "BEZIER": bezier_sweep = True - if ob.pov.curveshape in {'loft','birail'}: - n=0 + if ob.pov.curveshape in {'loft', 'birail'}: + n = 0 for spline in ob.data.splines: - n+=1 - tabWrite('#declare %s%s=spline {\n'%(dataname,n)) + n += 1 + tabWrite('#declare %s%s=spline {\n' % (dataname, n)) tabWrite('cubic_spline\n') lp = len(spline.points) - delta = 1/(lp) - d=-delta - point = spline.points[lp-1] - x,y,z,w = point.co[:] - tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z)) - d+=delta + delta = 1 / (lp) + d = -delta + point = spline.points[lp - 1] + x, y, z, w = point.co[:] + tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z)) + d += delta for point in spline.points: - x,y,z,w = point.co[:] - tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z)) - d+=delta + x, y, z, w = point.co[:] + tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z)) + d += delta for i in range(2): point = spline.points[i] - x,y,z,w = point.co[:] - tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z)) - d+=delta + x, y, z, w = point.co[:] + tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z)) + d += delta tabWrite('}\n') if ob.pov.curveshape in {'loft'}: n = len(ob.data.splines) - tabWrite('#declare %s = array[%s]{\n'%(dataname,(n+3))) - tabWrite('spline{%s%s},\n'%(dataname,n)) + tabWrite('#declare %s = array[%s]{\n' % (dataname, (n + 3))) + tabWrite('spline{%s%s},\n' % (dataname, n)) for i in range(n): - tabWrite('spline{%s%s},\n'%(dataname,(i+1))) - tabWrite('spline{%s1},\n'%(dataname)) - tabWrite('spline{%s2}\n'%(dataname)) + tabWrite('spline{%s%s},\n' % (dataname, (i + 1))) + tabWrite('spline{%s1},\n' % (dataname)) + tabWrite('spline{%s2}\n' % (dataname)) tabWrite('}\n') # Use some of the Meshmaker.inc macro, here inlined file.write('#macro CheckFileName(FileName)\n') @@ -931,8 +1115,12 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #if(Len>0)\n') file.write(' #if(file_exists(FileName))\n') file.write(' #if(Len>=4)\n') - file.write(' #local Ext=strlwr(substr(FileName,Len-3,4))\n') - file.write(' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n') + file.write( + ' #local Ext=strlwr(substr(FileName,Len-3,4))\n' + ) + file.write( + ' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n' + ) file.write(' #local Return=99;\n') file.write(' #else\n') file.write(' #local Return=0;\n') @@ -942,8 +1130,12 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #end\n') file.write(' #else\n') file.write(' #if(Len>=4)\n') - file.write(' #local Ext=strlwr(substr(FileName,Len-3,4))\n') - file.write(' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n') + file.write( + ' #local Ext=strlwr(substr(FileName,Len-3,4))\n' + ) + file.write( + ' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n' + ) file.write(' #if (strcmp(Ext,".obj")=0)\n') file.write(' #local Return=2;\n') file.write(' #end\n') @@ -971,7 +1163,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local Asc=asc(strupr(SplType));\n') file.write(' #if(Asc!=67 & Asc!=76 & Asc!=81) \n') file.write(' #local Asc=76;\n') - file.write(' #debug "\nWrong spline type defined (C/c/L/l/N/n/Q/q), using default linear_spline\\n"\n') + file.write( + ' #debug "\nWrong spline type defined (C/c/L/l/N/n/Q/q), using default linear_spline\\n"\n' + ) file.write(' #end\n') file.write(' spline {\n') file.write(' #switch (Asc)\n') @@ -1000,11 +1194,14 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' }\n') file.write('#end\n') - - file.write('#macro BuildWriteMesh2(VecArr, NormArr, UVArr, U, V, FileName)\n') - #suppressed some file checking from original macro because no more separate files + file.write( + '#macro BuildWriteMesh2(VecArr, NormArr, UVArr, U, V, FileName)\n' + ) + # suppressed some file checking from original macro because no more separate files file.write(' #local Write=0;\n') - file.write(' #debug concat("\\n\\n Building mesh2: \\n - vertex_vectors\\n")\n') + file.write( + ' #debug concat("\\n\\n Building mesh2: \\n - vertex_vectors\\n")\n' + ) file.write(' #local NumVertices=dimension_size(VecArr,1);\n') file.write(' #switch (Write)\n') file.write(' #case(1)\n') @@ -1029,7 +1226,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(4)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "#declare VertexVectors= array[",str(NumVertices,0,0),"] {\\n "\n') + file.write( + ' "#declare VertexVectors= array[",str(NumVertices,0,0),"] {\\n "\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #end\n') @@ -1046,13 +1245,17 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "v ", VecArr[I].x," ", VecArr[I].y," ", VecArr[I].z,"\\n"\n') + file.write( + ' "v ", VecArr[I].x," ", VecArr[I].y," ", VecArr[I].z,"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' VecArr[I].x,",", VecArr[I].y,",", VecArr[I].z,",\\n"\n') + file.write( + ' VecArr[I].x,",", VecArr[I].y,",", VecArr[I].z,",\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(4)\n') @@ -1095,7 +1298,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "# Normals: ",str(NumVertices,0,0),"\\n"\n') + file.write( + ' "# Normals: ",str(NumVertices,0,0),"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') @@ -1104,7 +1309,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(4)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "#declare NormalVectors= array[",str(NumVertices,0,0),"] {\\n "\n') + file.write( + ' "#declare NormalVectors= array[",str(NumVertices,0,0),"] {\\n "\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #end\n') @@ -1120,13 +1327,17 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "vn ", NormArr[I].x," ", NormArr[I].y," ", NormArr[I].z,"\\n"\n') + file.write( + ' "vn ", NormArr[I].x," ", NormArr[I].y," ", NormArr[I].z,"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' NormArr[I].x,",", NormArr[I].y,",", NormArr[I].z,",\\n"\n') + file.write( + ' NormArr[I].x,",", NormArr[I].y,",", NormArr[I].z,",\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(4)\n') @@ -1169,16 +1380,22 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "# UV-vectors: ",str(NumVertices,0,0),"\\n"\n') + file.write( + ' "# UV-vectors: ",str(NumVertices,0,0),"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') - file.write(' // do nothing, *.pcm does not support uv-vectors\n') + file.write( + ' // do nothing, *.pcm does not support uv-vectors\n' + ) file.write(' #break\n') file.write(' #case(4)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "#declare UVVectors= array[",str(NumVertices,0,0),"] {\\n "\n') + file.write( + ' "#declare UVVectors= array[",str(NumVertices,0,0),"] {\\n "\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #end\n') @@ -1194,7 +1411,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "vt ", UVArr[I].u," ", UVArr[I].v,"\\n"\n') + file.write( + ' "vt ", UVArr[I].u," ", UVArr[I].v,"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') @@ -1252,7 +1471,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #case(4)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "#declare FaceIndices= array[",str(NumFaces,0,0),"] {\\n "\n') + file.write( + ' "#declare FaceIndices= array[",str(NumFaces,0,0),"] {\\n "\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #end\n') @@ -1265,32 +1486,46 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local J=0;\n') file.write(' #while (J<U)\n') file.write(' #local Ind=(I*U)+I+J;\n') - file.write(' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n') + file.write( + ' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n' + ) file.write(' #switch(Write)\n') file.write(' #case(1)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n') + file.write( + ' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(2)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' "f ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+1+1,"/",Ind+1+1,"/",Ind+1+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n",\n') - file.write(' "f ",Ind+U+1+1,"/",Ind+U+1+1,"/",Ind+U+1+1," ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n"\n') + file.write( + ' "f ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+1+1,"/",Ind+1+1,"/",Ind+1+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n",\n' + ) + file.write( + ' "f ",Ind+U+1+1,"/",Ind+U+1+1,"/",Ind+U+1+1," ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(3)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' Ind,",",Ind+NumVertices,",",Ind+1,",",Ind+1+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n') - file.write(' Ind+U+1,",",Ind+U+1+NumVertices,",",Ind,",",Ind+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n') + file.write( + ' Ind,",",Ind+NumVertices,",",Ind+1,",",Ind+1+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n' + ) + file.write( + ' Ind+U+1,",",Ind+U+1+NumVertices,",",Ind,",",Ind+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #case(4)\n') file.write(' #write(\n') file.write(' MeshFile,\n') - file.write(' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n') + file.write( + ' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n' + ) file.write(' )\n') file.write(' #break\n') file.write(' #end\n') @@ -1328,16 +1563,22 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' }\n') file.write('#end\n') - file.write('#macro MSM(SplineArray, SplRes, Interp_type, InterpRes, FileName)\n') + file.write( + '#macro MSM(SplineArray, SplRes, Interp_type, InterpRes, FileName)\n' + ) file.write(' #declare Build=CheckFileName(FileName);\n') file.write(' #if(Build=0)\n') - file.write(' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n') + file.write( + ' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n' + ) file.write(' #include FileName\n') file.write(' object{Surface}\n') file.write(' #else\n') file.write(' #local NumVertices=(SplRes+1)*(InterpRes+1);\n') file.write(' #local NumFaces=SplRes*InterpRes*2;\n') - file.write(' #debug concat("\\n Calculating ",str(NumVertices,0,0)," vertices for ", str(NumFaces,0,0)," triangles\\n\\n")\n') + file.write( + ' #debug concat("\\n Calculating ",str(NumVertices,0,0)," vertices for ", str(NumFaces,0,0)," triangles\\n\\n")\n' + ) file.write(' #local VecArr=array[NumVertices]\n') file.write(' #local NormArr=array[NumVertices]\n') file.write(' #local UVArr=array[NumVertices]\n') @@ -1353,22 +1594,42 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local I=0;\n') file.write(' #if (Pos=0)\n') file.write(' #while (I<N)\n') - file.write(' #local Spl=spline{SplineArray[I]}\n') - file.write(' #local TempSplArr0[I]=<0,0,0>+Spl(Pos);\n') - file.write(' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n') - file.write(' #local TempSplArr2[I]=<0,0,0>+Spl(Pos-PosStep);\n') + file.write( + ' #local Spl=spline{SplineArray[I]}\n' + ) + file.write( + ' #local TempSplArr0[I]=<0,0,0>+Spl(Pos);\n' + ) + file.write( + ' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n' + ) + file.write( + ' #local TempSplArr2[I]=<0,0,0>+Spl(Pos-PosStep);\n' + ) file.write(' #local I=I+1;\n') file.write(' #end\n') - file.write(' #local S0=BuildSpline(TempSplArr0, Interp_type)\n') - file.write(' #local S1=BuildSpline(TempSplArr1, Interp_type)\n') - file.write(' #local S2=BuildSpline(TempSplArr2, Interp_type)\n') + file.write( + ' #local S0=BuildSpline(TempSplArr0, Interp_type)\n' + ) + file.write( + ' #local S1=BuildSpline(TempSplArr1, Interp_type)\n' + ) + file.write( + ' #local S2=BuildSpline(TempSplArr2, Interp_type)\n' + ) file.write(' #else\n') file.write(' #while (I<N)\n') - file.write(' #local Spl=spline{SplineArray[I]}\n') - file.write(' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n') + file.write( + ' #local Spl=spline{SplineArray[I]}\n' + ) + file.write( + ' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n' + ) file.write(' #local I=I+1;\n') file.write(' #end\n') - file.write(' #local S1=BuildSpline(TempSplArr1, Interp_type)\n') + file.write( + ' #local S1=BuildSpline(TempSplArr1, Interp_type)\n' + ) file.write(' #end\n') file.write(' #local J=0;\n') file.write(' #while (J<=1)\n') @@ -1385,7 +1646,9 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local N2=vcross(B2,B3);\n') file.write(' #local N3=vcross(B3,B4);\n') file.write(' #local N4=vcross(B4,B1);\n') - file.write(' #local Norm=vnormalize((N1+N2+N3+N4));\n') + file.write( + ' #local Norm=vnormalize((N1+N2+N3+N4));\n' + ) file.write(' #local VecArr[Count]=P0;\n') file.write(' #local NormArr[Count]=Norm;\n') file.write(' #local UVArr[Count]=<J,Pos>;\n') @@ -1394,23 +1657,33 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #end\n') file.write(' #local S2=spline{S0}\n') file.write(' #local S0=spline{S1}\n') - file.write(' #debug concat("\\r Done ", str(Count,0,0)," vertices : ", str(100*Count/NumVertices,0,2)," %")\n') + file.write( + ' #debug concat("\\r Done ", str(Count,0,0)," vertices : ", str(100*Count/NumVertices,0,2)," %")\n' + ) file.write(' #local Pos=Pos+PosStep;\n') file.write(' #end\n') - file.write(' BuildWriteMesh2(VecArr, NormArr, UVArr, InterpRes, SplRes, "")\n') + file.write( + ' BuildWriteMesh2(VecArr, NormArr, UVArr, InterpRes, SplRes, "")\n' + ) file.write(' #end\n') file.write('#end\n\n') - file.write('#macro Coons(Spl1, Spl2, Spl3, Spl4, Iter_U, Iter_V, FileName)\n') + file.write( + '#macro Coons(Spl1, Spl2, Spl3, Spl4, Iter_U, Iter_V, FileName)\n' + ) file.write(' #declare Build=CheckFileName(FileName);\n') file.write(' #if(Build=0)\n') - file.write(' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n') + file.write( + ' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n' + ) file.write(' #include FileName\n') file.write(' object{Surface}\n') file.write(' #else\n') file.write(' #local NumVertices=(Iter_U+1)*(Iter_V+1);\n') file.write(' #local NumFaces=Iter_U*Iter_V*2;\n') - file.write(' #debug concat("\\n Calculating ", str(NumVertices,0,0), " vertices for ",str(NumFaces,0,0), " triangles\\n\\n")\n') + file.write( + ' #debug concat("\\n Calculating ", str(NumVertices,0,0), " vertices for ",str(NumFaces,0,0), " triangles\\n\\n")\n' + ) file.write(' #declare VecArr=array[NumVertices] \n') file.write(' #declare NormArr=array[NumVertices] \n') file.write(' #local UVArr=array[NumVertices] \n') @@ -1427,21 +1700,31 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local J=0;\n') file.write(' #while (J<=1)\n') file.write(' #local Jm=1-J;\n') - file.write(' #local C0=Im*Jm*(Spl1_0)+Im*J*(Spl2_0)+I*J*(Spl3_0)+I*Jm*(Spl4_0);\n') - file.write(' #local P0=LInterpolate(I, Spl1(J), Spl3(Jm)) + \n') - file.write(' LInterpolate(Jm, Spl2(I), Spl4(Im))-C0;\n') + file.write( + ' #local C0=Im*Jm*(Spl1_0)+Im*J*(Spl2_0)+I*J*(Spl3_0)+I*Jm*(Spl4_0);\n' + ) + file.write( + ' #local P0=LInterpolate(I, Spl1(J), Spl3(Jm)) + \n' + ) + file.write( + ' LInterpolate(Jm, Spl2(I), Spl4(Im))-C0;\n' + ) file.write(' #declare VecArr[Count]=P0;\n') file.write(' #local UVArr[Count]=<J,I>;\n') file.write(' #local J=J+UStep;\n') file.write(' #local Count=Count+1;\n') file.write(' #end\n') file.write(' #debug concat(\n') - file.write(' "\r Done ", str(Count,0,0)," vertices : ",\n') + file.write( + ' "\r Done ", str(Count,0,0)," vertices : ",\n' + ) file.write(' str(100*Count/NumVertices,0,2)," %"\n') file.write(' )\n') file.write(' #local I=I+VStep;\n') file.write(' #end\n') - file.write(' #debug "\r Normals "\n') + file.write( + ' #debug "\r Normals "\n' + ) file.write(' #local Count=0;\n') file.write(' #local I=0;\n') file.write(' #while (I<=Iter_V)\n') @@ -1460,12 +1743,16 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local P2=VecArr[Ind+1];\n') file.write(' #end\n') file.write(' #if (I=0)\n') - file.write(' #local P3=P0+(P0-VecArr[Ind+Iter_U+1]);\n') + file.write( + ' #local P3=P0+(P0-VecArr[Ind+Iter_U+1]);\n' + ) file.write(' #else\n') file.write(' #local P3=VecArr[Ind-Iter_U-1];\n') file.write(' #end\n') file.write(' #if (I=Iter_V)\n') - file.write(' #local P4=P0+(P0-VecArr[Ind-Iter_U-1]);\n') + file.write( + ' #local P4=P0+(P0-VecArr[Ind-Iter_U-1]);\n' + ) file.write(' #else\n') file.write(' #local P4=VecArr[Ind+Iter_U+1];\n') file.write(' #end\n') @@ -1482,21 +1769,28 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' #local J=J+1;\n') file.write(' #local Count=Count+1;\n') file.write(' #end\n') - file.write(' #debug concat("\r Done ", str(Count,0,0)," normals : ",str(100*Count/NumVertices,0,2), " %")\n') + file.write( + ' #debug concat("\r Done ", str(Count,0,0)," normals : ",str(100*Count/NumVertices,0,2), " %")\n' + ) file.write(' #local I=I+1;\n') file.write(' #end\n') - file.write(' BuildWriteMesh2(VecArr, NormArr, UVArr, Iter_U, Iter_V, FileName)\n') + file.write( + ' BuildWriteMesh2(VecArr, NormArr, UVArr, Iter_U, Iter_V, FileName)\n' + ) file.write(' #end\n') file.write('#end\n\n') # Empty curves - if len(ob.data.splines)==0: + if len(ob.data.splines) == 0: tabWrite("\n//dummy sphere to represent empty curve location\n") - tabWrite("#declare %s =\n"%dataname) - tabWrite("sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n" % (ob.location.x, ob.location.y, ob.location.z)) # ob.name > povdataname) + tabWrite("#declare %s =\n" % dataname) + tabWrite( + "sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n" + % (ob.location.x, ob.location.y, ob.location.z) + ) # ob.name > povdataname) # And non empty curves else: if bezier_sweep == False: - tabWrite("#declare %s =\n"%dataname) + tabWrite("#declare %s =\n" % dataname) if ob.pov.curveshape == 'sphere_sweep' and bezier_sweep == False: tabWrite("union {\n") for spl in ob.data.splines: @@ -1504,155 +1798,212 @@ def write_pov(filename, scene=None, info_callback=None): spl_type = "linear" if spl.type == "NURBS": spl_type = "cubic" - points=spl.points - numPoints=len(points) + points = spl.points + numPoints = len(points) if spl.use_cyclic_u: - numPoints+=3 + numPoints += 3 - tabWrite("sphere_sweep { %s_spline %s,\n"%(spl_type,numPoints)) + tabWrite( + "sphere_sweep { %s_spline %s,\n" + % (spl_type, numPoints) + ) if spl.use_cyclic_u: - pt1 = points[len(points)-1] + pt1 = points[len(points) - 1] wpt1 = pt1.co - tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt1[0], wpt1[1], wpt1[2], pt1.radius*ob.data.bevel_depth)) + tabWrite( + "<%.4g,%.4g,%.4g>,%.4g\n" + % ( + wpt1[0], + wpt1[1], + wpt1[2], + pt1.radius * ob.data.bevel_depth, + ) + ) for pt in points: wpt = pt.co - tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt[0], wpt[1], wpt[2], pt.radius*ob.data.bevel_depth)) + tabWrite( + "<%.4g,%.4g,%.4g>,%.4g\n" + % ( + wpt[0], + wpt[1], + wpt[2], + pt.radius * ob.data.bevel_depth, + ) + ) if spl.use_cyclic_u: - for i in range (0,2): - endPt=points[i] + for i in range(0, 2): + endPt = points[i] wpt = endPt.co - tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt[0], wpt[1], wpt[2], endPt.radius*ob.data.bevel_depth)) - + tabWrite( + "<%.4g,%.4g,%.4g>,%.4g\n" + % ( + wpt[0], + wpt[1], + wpt[2], + endPt.radius * ob.data.bevel_depth, + ) + ) tabWrite("}\n") # below not used yet? if ob.pov.curveshape == 'sor': for spl in ob.data.splines: - if spl.type in {'POLY','NURBS'}: - points=spl.points - numPoints=len(points) - tabWrite("sor { %s,\n"%numPoints) + if spl.type in {'POLY', 'NURBS'}: + points = spl.points + numPoints = len(points) + tabWrite("sor { %s,\n" % numPoints) for pt in points: wpt = pt.co - tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1])) + tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1])) else: tabWrite("box { 0,0\n") - if ob.pov.curveshape in {'lathe','prism'}: + if ob.pov.curveshape in {'lathe', 'prism'}: spl = ob.data.splines[0] if spl.type == "BEZIER": - points=spl.bezier_points - lenCur=len(points)-1 - lenPts=lenCur*4 + points = spl.bezier_points + lenCur = len(points) - 1 + lenPts = lenCur * 4 ifprism = '' if ob.pov.curveshape in {'prism'}: height = ob.data.extrude - ifprism = '-%s, %s,'%(height, height) - lenCur+=1 - lenPts+=4 - tabWrite("%s { bezier_spline %s %s,\n"%(ob.pov.curveshape,ifprism,lenPts)) - for i in range(0,lenCur): - p1=points[i].co - pR=points[i].handle_right - end = i+1 - if i == lenCur-1 and ob.pov.curveshape in {'prism'}: + ifprism = '-%s, %s,' % (height, height) + lenCur += 1 + lenPts += 4 + tabWrite( + "%s { bezier_spline %s %s,\n" + % (ob.pov.curveshape, ifprism, lenPts) + ) + for i in range(0, lenCur): + p1 = points[i].co + pR = points[i].handle_right + end = i + 1 + if i == lenCur - 1 and ob.pov.curveshape in {'prism'}: end = 0 - pL=points[end].handle_left - p2=points[end].co - line="<%.4g,%.4g>"%(p1[0],p1[1]) - line+="<%.4g,%.4g>"%(pR[0],pR[1]) - line+="<%.4g,%.4g>"%(pL[0],pL[1]) - line+="<%.4g,%.4g>"%(p2[0],p2[1]) - tabWrite("%s\n" %line) + pL = points[end].handle_left + p2 = points[end].co + line = "<%.4g,%.4g>" % (p1[0], p1[1]) + line += "<%.4g,%.4g>" % (pR[0], pR[1]) + line += "<%.4g,%.4g>" % (pL[0], pL[1]) + line += "<%.4g,%.4g>" % (p2[0], p2[1]) + tabWrite("%s\n" % line) else: - points=spl.points - lenCur=len(points) - lenPts=lenCur + points = spl.points + lenCur = len(points) + lenPts = lenCur ifprism = '' if ob.pov.curveshape in {'prism'}: height = ob.data.extrude - ifprism = '-%s, %s,'%(height, height) - lenPts+=3 + ifprism = '-%s, %s,' % (height, height) + lenPts += 3 spl_type = 'quadratic' if spl.type == 'POLY': spl_type = 'linear' - tabWrite("%s { %s_spline %s %s,\n"%(ob.pov.curveshape,spl_type,ifprism,lenPts)) + tabWrite( + "%s { %s_spline %s %s,\n" + % (ob.pov.curveshape, spl_type, ifprism, lenPts) + ) if ob.pov.curveshape in {'prism'}: - pt = points[len(points)-1] + pt = points[len(points) - 1] wpt = pt.co - tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1])) + tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1])) for pt in points: wpt = pt.co - tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1])) + tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1])) if ob.pov.curveshape in {'prism'}: for i in range(2): pt = points[i] wpt = pt.co - tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1])) + tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1])) if bezier_sweep: for p in range(len(ob.data.splines)): br = [] depth = ob.data.bevel_depth spl = ob.data.splines[p] - points=spl.bezier_points - lenCur = len(points)-1 - numPoints = lenCur*4 + points = spl.bezier_points + lenCur = len(points) - 1 + numPoints = lenCur * 4 if spl.use_cyclic_u: lenCur += 1 numPoints += 4 - tabWrite("#declare %s_points_%s = array[%s]{\n"%(dataname,p,numPoints)) + tabWrite( + "#declare %s_points_%s = array[%s]{\n" + % (dataname, p, numPoints) + ) for i in range(lenCur): - p1=points[i].co - pR=points[i].handle_right - end = i+1 + p1 = points[i].co + pR = points[i].handle_right + end = i + 1 if spl.use_cyclic_u and i == (lenCur - 1): end = 0 - pL=points[end].handle_left - p2=points[end].co + pL = points[end].handle_left + p2 = points[end].co r3 = points[end].radius * depth r0 = points[i].radius * depth - r1 = 2/3*r0 + 1/3*r3 - r2 = 1/3*r0 + 2/3*r3 - br.append((r0,r1,r2,r3)) - line="<%.4g,%.4g,%.4f>"%(p1[0],p1[1],p1[2]) - line+="<%.4g,%.4g,%.4f>"%(pR[0],pR[1],pR[2]) - line+="<%.4g,%.4g,%.4f>"%(pL[0],pL[1],pL[2]) - line+="<%.4g,%.4g,%.4f>"%(p2[0],p2[1],p2[2]) - tabWrite("%s\n" %line) + r1 = 2 / 3 * r0 + 1 / 3 * r3 + r2 = 1 / 3 * r0 + 2 / 3 * r3 + br.append((r0, r1, r2, r3)) + line = "<%.4g,%.4g,%.4f>" % (p1[0], p1[1], p1[2]) + line += "<%.4g,%.4g,%.4f>" % (pR[0], pR[1], pR[2]) + line += "<%.4g,%.4g,%.4f>" % (pL[0], pL[1], pL[2]) + line += "<%.4g,%.4g,%.4f>" % (p2[0], p2[1], p2[2]) + tabWrite("%s\n" % line) tabWrite("}\n") - tabWrite("#declare %s_radii_%s = array[%s]{\n"%(dataname,p,len(br)*4)) + tabWrite( + "#declare %s_radii_%s = array[%s]{\n" + % (dataname, p, len(br) * 4) + ) for Tuple in br: - tabWrite('%.4f,%.4f,%.4f,%.4f\n'%(Tuple[0],Tuple[1],Tuple[2],Tuple[3])) + tabWrite( + '%.4f,%.4f,%.4f,%.4f\n' + % (Tuple[0], Tuple[1], Tuple[2], Tuple[3]) + ) tabWrite("}\n") - if len(ob.data.splines)== 1: - tabWrite('#declare %s = object{\n'%dataname) - tabWrite(' Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s) \n'%(ob.data.resolution_u,dataname,p,dataname,p)) + if len(ob.data.splines) == 1: + tabWrite('#declare %s = object{\n' % dataname) + tabWrite( + ' Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s) \n' + % (ob.data.resolution_u, dataname, p, dataname, p) + ) else: - tabWrite('#declare %s = union{\n'%dataname) + tabWrite('#declare %s = union{\n' % dataname) for p in range(len(ob.data.splines)): - tabWrite(' object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s)} \n'%(ob.data.resolution_u,dataname,p,dataname,p)) - #tabWrite('#include "bezier_spheresweep.inc"\n') #now inlined - # tabWrite('#declare %s = object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_bezier_points, %.4f) \n'%(dataname,ob.data.resolution_u,dataname,ob.data.bevel_depth)) + tabWrite( + ' object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s)} \n' + % (ob.data.resolution_u, dataname, p, dataname, p) + ) + # tabWrite('#include "bezier_spheresweep.inc"\n') #now inlined + # tabWrite('#declare %s = object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_bezier_points, %.4f) \n'%(dataname,ob.data.resolution_u,dataname,ob.data.bevel_depth)) if ob.pov.curveshape in {'loft'}: - tabWrite('object {MSM(%s,%s,"c",%s,"")\n'%(dataname,ob.pov.res_u,ob.pov.res_v)) + tabWrite( + 'object {MSM(%s,%s,"c",%s,"")\n' + % (dataname, ob.pov.res_u, ob.pov.res_v) + ) if ob.pov.curveshape in {'birail'}: - splines = '%s1,%s2,%s3,%s4'%(dataname,dataname,dataname,dataname) - tabWrite('object {Coons(%s, %s, %s, "")\n'%(splines,ob.pov.res_u,ob.pov.res_v)) + splines = '%s1,%s2,%s3,%s4' % ( + dataname, + dataname, + dataname, + dataname, + ) + tabWrite( + 'object {Coons(%s, %s, %s, "")\n' + % (splines, ob.pov.res_u, ob.pov.res_v) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) + # tabWrite("texture {%s}\n"%povMatName) if ob.pov.curveshape in {'prism'}: tabWrite("rotate <90,0,0>\n") - tabWrite("scale y*-1\n" ) + tabWrite("scale y*-1\n") tabWrite("}\n") -################################################################# - + ################################################################# def exportMeta(metas): """write all POV blob primitives and Blender Metas to exported file """ @@ -1667,94 +2018,229 @@ def write_pov(filename, scene=None, info_callback=None): prefix = ob.name.split(".")[0] if not prefix in meta_group: meta_group[prefix] = ob # .data.threshold - elems = [(elem, ob) for elem in ob.data.elements if elem.type in {'BALL', 'ELLIPSOID','CAPSULE','CUBE','PLANE'}] + elems = [ + (elem, ob) + for elem in ob.data.elements + if elem.type + in {'BALL', 'ELLIPSOID', 'CAPSULE', 'CUBE', 'PLANE'} + ] if prefix in meta_elems: meta_elems[prefix].extend(elems) else: meta_elems[prefix] = elems # empty metaball - if len(elems)==0: + if len(elems) == 0: tabWrite("\n//dummy sphere to represent empty meta location\n") - tabWrite("sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n" % (ob.location.x, ob.location.y, ob.location.z)) # ob.name > povdataname) + tabWrite( + "sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n" + % (ob.location.x, ob.location.y, ob.location.z) + ) # ob.name > povdataname) # other metaballs else: for mg, ob in meta_group.items(): - if len(meta_elems[mg])!=0: - tabWrite("blob{threshold %.4g // %s \n" % (ob.data.threshold, mg)) + if len(meta_elems[mg]) != 0: + tabWrite( + "blob{threshold %.4g // %s \n" + % (ob.data.threshold, mg) + ) for elems in meta_elems[mg]: elem = elems[0] loc = elem.co stiffness = elem.stiffness if elem.use_negative: - stiffness = - stiffness + stiffness = -stiffness if elem.type == 'BALL': - tabWrite("sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g " % - (loc.x, loc.y, loc.z, elem.radius, stiffness)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g " + % ( + loc.x, + loc.y, + loc.z, + elem.radius, + stiffness, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") elif elem.type == 'ELLIPSOID': - tabWrite("sphere{ <%.6g, %.6g, %.6g>,%.4g,%.4g " % - (loc.x / elem.size_x, loc.y / elem.size_y, loc.z / elem.size_z, - elem.radius, stiffness)) - tabWrite("scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "sphere{ <%.6g, %.6g, %.6g>,%.4g,%.4g " + % ( + loc.x / elem.size_x, + loc.y / elem.size_y, + loc.z / elem.size_z, + elem.radius, + stiffness, + ) + ) + tabWrite( + "scale <%.6g, %.6g, %.6g>" + % (elem.size_x, elem.size_y, elem.size_z) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") elif elem.type == 'CAPSULE': - tabWrite("cylinder{ <%.6g, %.6g, %.6g>,<%.6g, %.6g, %.6g>,%.4g,%.4g " % - ((loc.x - elem.size_x), (loc.y), (loc.z), - (loc.x + elem.size_x), (loc.y), (loc.z), - elem.radius, stiffness)) - #tabWrite("scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder{ <%.6g, %.6g, %.6g>,<%.6g, %.6g, %.6g>,%.4g,%.4g " + % ( + (loc.x - elem.size_x), + (loc.y), + (loc.z), + (loc.x + elem.size_x), + (loc.y), + (loc.z), + elem.radius, + stiffness, + ) + ) + # tabWrite("scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z)) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") elif elem.type == 'CUBE': - tabWrite("cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n" % (elem.radius*2.0, stiffness/4.0, loc.x, loc.y, loc.z, elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n" + % ( + elem.radius * 2.0, + stiffness / 4.0, + loc.x, + loc.y, + loc.z, + elem.size_x, + elem.size_y, + elem.size_z, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") - tabWrite("cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n" % (elem.radius*2.0, stiffness/4.0, loc.x, loc.y, loc.z, elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n" + % ( + elem.radius * 2.0, + stiffness / 4.0, + loc.x, + loc.y, + loc.z, + elem.size_x, + elem.size_y, + elem.size_z, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") - tabWrite("cylinder { -z*8, +z*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1,1/4> scale <%.6g, %.6g, %.6g>\n" % (elem.radius*2.0, stiffness/4.0, loc.x, loc.y, loc.z, elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder { -z*8, +z*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1,1/4> scale <%.6g, %.6g, %.6g>\n" + % ( + elem.radius * 2.0, + stiffness / 4.0, + loc.x, + loc.y, + loc.z, + elem.size_x, + elem.size_y, + elem.size_z, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") elif elem.type == 'PLANE': - tabWrite("cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n" % (elem.radius*2.0, stiffness/4.0, loc.x, loc.y, loc.z, elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n" + % ( + elem.radius * 2.0, + stiffness / 4.0, + loc.x, + loc.y, + loc.z, + elem.size_x, + elem.size_y, + elem.size_z, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") - tabWrite("cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n" % (elem.radius*2.0, stiffness/4.0, loc.x, loc.y, loc.z, elem.size_x, elem.size_y, elem.size_z)) - writeMatrix(global_matrix @ elems[1].matrix_world) + tabWrite( + "cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n" + % ( + elem.radius * 2.0, + stiffness / 4.0, + loc.x, + loc.y, + loc.z, + elem.size_x, + elem.size_y, + elem.size_z, + ) + ) + writeMatrix( + global_matrix @ elems[1].matrix_world + ) tabWrite("}\n") try: - material = elems[1].data.materials[0] # lame! - blender cant do enything else. + material = elems[1].data.materials[ + 0 + ] # lame! - blender cant do enything else. except: material = None if material: diffuse_color = material.diffuse_color trans = 1.0 - material.pov.alpha - if material.use_transparency and material.transparency_method == 'RAYTRACE': - povFilter = material.pov_raytrace_transparency.filter * (1.0 - material.alpha) + if ( + material.use_transparency + and material.transparency_method == 'RAYTRACE' + ): + povFilter = ( + material.pov_raytrace_transparency.filter + * (1.0 - material.alpha) + ) trans = (1.0 - material.pov.alpha) - povFilter else: povFilter = 0.0 material_finish = materialNames[material.name] - tabWrite("pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n" % - (diffuse_color[0], diffuse_color[1], diffuse_color[2], - povFilter, trans)) - tabWrite("finish{%s} " % safety(material_finish, Level=2)) + tabWrite( + "pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n" + % ( + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + povFilter, + trans, + ) + ) + tabWrite( + "finish{%s} " % safety(material_finish, Level=2) + ) else: - tabWrite("pigment{srgb 1} finish{%s} " % (safety(DEF_MAT_NAME, Level=2))) - + tabWrite( + "pigment{srgb 1} finish{%s} " + % (safety(DEF_MAT_NAME, Level=2)) + ) writeObjectMaterial(material, ob) - #writeObjectMaterial(material, elems[1]) - tabWrite("radiosity{importance %3g}\n" % ob.pov.importance_value) + # writeObjectMaterial(material, elems[1]) + tabWrite( + "radiosity{importance %3g}\n" + % ob.pov.importance_value + ) tabWrite("}\n\n") # End of Metaball block - ''' meta = ob.data @@ -1832,31 +2318,31 @@ def write_pov(filename, scene=None, info_callback=None): if comments and len(metas) >= 1: file.write("\n") ''' -# objectNames = {} + # objectNames = {} 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 ... -# if hasattr(ob, 'material_slots'): -# for ms in ob.material_slots: -# if ms.material is not None and ms.link == 'OBJECT': -# if ms.material in obmatslist: -# return False -# else: -# obmatslist.append(ms.material) -# return True -# def hasObjectMaterial(ob): -# # Grab materials attached to object instances ... -# if hasattr(ob, 'material_slots'): -# for ms in ob.material_slots: -# if ms.material is not None and ms.link == 'OBJECT': -# # If there is at least one material slot linked to the object -# # and not the data (mesh), always create a new, "private" data instance. -# return True -# return False + # obmatslist = [] + # def hasUniqueMaterial(): + # # Grab materials attached to object instances ... + # if hasattr(ob, 'material_slots'): + # for ms in ob.material_slots: + # if ms.material is not None and ms.link == 'OBJECT': + # if ms.material in obmatslist: + # return False + # else: + # obmatslist.append(ms.material) + # return True + # def hasObjectMaterial(ob): + # # Grab materials attached to object instances ... + # if hasattr(ob, 'material_slots'): + # for ms in ob.material_slots: + # if ms.material is not None and ms.link == 'OBJECT': + # # If there is at least one material slot linked to the object + # # and not the data (mesh), always create a new, "private" data instance. + # return True + # return False # For objects using local material(s) only! # This is a mapping between a tuple (dataname, materialnames, ...), and the POV dataname. # As only objects using: @@ -1914,11 +2400,10 @@ def write_pov(filename, scene=None, info_callback=None): data_ref[dataname] = [(name, MatrixAsPovString(matrix))] return dataname - def exportSmoke(smoke_obj_name): - #if LuxManager.CurrentScene.name == 'preview': - #return 1, 1, 1, 1.0 - #else: + # if LuxManager.CurrentScene.name == 'preview': + # return 1, 1, 1, 1.0 + # else: flowtype = -1 smoke_obj = bpy.data.objects[smoke_obj_name] domain = None @@ -1942,7 +2427,7 @@ def write_pov(filename, scene=None, info_callback=None): eps = 0.000001 if domain is not None: - #if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 71: + # if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 71: # Blender version 2.71 supports direct access to smoke data structure set = mod.domain_settings channeldata = [] @@ -1952,12 +2437,12 @@ def write_pov(filename, scene=None, info_callback=None): ## Usage en voxel texture: # channeldata = [] # if channel == 'density': - # for v in set.density_grid: - # channeldata.append(v.real) + # for v in set.density_grid: + # channeldata.append(v.real) # if channel == 'fire': - # for v in set.flame_grid: - # channeldata.append(v.real) + # for v in set.flame_grid: + # channeldata.append(v.real) resolution = set.resolution_max big_res = [] @@ -1970,77 +2455,84 @@ def write_pov(filename, scene=None, info_callback=None): big_res[1] = big_res[1] * (set.amplify + 1) big_res[2] = big_res[2] * (set.amplify + 1) # else: - # p = [] - ##gather smoke domain settings - # BBox = domain.bound_box - # p.append([BBox[0][0], BBox[0][1], BBox[0][2]]) - # p.append([BBox[6][0], BBox[6][1], BBox[6][2]]) - # set = mod.domain_settings - # resolution = set.resolution_max - # smokecache = set.point_cache - # ret = read_cache(smokecache, set.use_high_resolution, set.amplify + 1, flowtype) - # res_x = ret[0] - # res_y = ret[1] - # res_z = ret[2] - # density = ret[3] - # fire = ret[4] - - # if res_x * res_y * res_z > 0: - ##new cache format - # big_res = [] - # big_res.append(res_x) - # big_res.append(res_y) - # big_res.append(res_z) - # else: - # max = domain.dimensions[0] - # if (max - domain.dimensions[1]) < -eps: - # max = domain.dimensions[1] - - # if (max - domain.dimensions[2]) < -eps: - # max = domain.dimensions[2] - - # big_res = [int(round(resolution * domain.dimensions[0] / max, 0)), - # int(round(resolution * domain.dimensions[1] / max, 0)), - # int(round(resolution * domain.dimensions[2] / max, 0))] - - # if set.use_high_resolution: - # big_res = [big_res[0] * (set.amplify + 1), big_res[1] * (set.amplify + 1), - # big_res[2] * (set.amplify + 1)] - - # if channel == 'density': - # channeldata = density - - # if channel == 'fire': - # channeldata = fire - - # sc_fr = '%s/%s/%s/%05d' % (efutil.export_path, efutil.scene_filename(), bpy.context.scene.name, bpy.context.scene.frame_current) - # if not os.path.exists( sc_fr ): - # os.makedirs(sc_fr) - # - # smoke_filename = '%s.smoke' % bpy.path.clean_name(domain.name) - # smoke_path = '/'.join([sc_fr, smoke_filename]) - # - # with open(smoke_path, 'wb') as smoke_file: - # # Binary densitygrid file format - # # - # # File header - # smoke_file.write(b'SMOKE') #magic number - # smoke_file.write(struct.pack('<I', big_res[0])) - # smoke_file.write(struct.pack('<I', big_res[1])) - # smoke_file.write(struct.pack('<I', big_res[2])) - # Density data - # smoke_file.write(struct.pack('<%df'%len(channeldata), *channeldata)) - # - # LuxLog('Binary SMOKE file written: %s' % (smoke_path)) - - #return big_res[0], big_res[1], big_res[2], channeldata - - mydf3 = df3.df3(big_res[0],big_res[1],big_res[2]) + # p = [] + ##gather smoke domain settings + # BBox = domain.bound_box + # p.append([BBox[0][0], BBox[0][1], BBox[0][2]]) + # p.append([BBox[6][0], BBox[6][1], BBox[6][2]]) + # set = mod.domain_settings + # resolution = set.resolution_max + # smokecache = set.point_cache + # ret = read_cache(smokecache, set.use_high_resolution, set.amplify + 1, flowtype) + # res_x = ret[0] + # res_y = ret[1] + # res_z = ret[2] + # density = ret[3] + # fire = ret[4] + + # if res_x * res_y * res_z > 0: + ##new cache format + # big_res = [] + # big_res.append(res_x) + # big_res.append(res_y) + # big_res.append(res_z) + # else: + # max = domain.dimensions[0] + # if (max - domain.dimensions[1]) < -eps: + # max = domain.dimensions[1] + + # if (max - domain.dimensions[2]) < -eps: + # max = domain.dimensions[2] + + # big_res = [int(round(resolution * domain.dimensions[0] / max, 0)), + # int(round(resolution * domain.dimensions[1] / max, 0)), + # int(round(resolution * domain.dimensions[2] / max, 0))] + + # if set.use_high_resolution: + # big_res = [big_res[0] * (set.amplify + 1), big_res[1] * (set.amplify + 1), + # big_res[2] * (set.amplify + 1)] + + # if channel == 'density': + # channeldata = density + + # if channel == 'fire': + # channeldata = fire + + # sc_fr = '%s/%s/%s/%05d' % (efutil.export_path, efutil.scene_filename(), bpy.context.scene.name, bpy.context.scene.frame_current) + # if not os.path.exists( sc_fr ): + # os.makedirs(sc_fr) + # + # smoke_filename = '%s.smoke' % bpy.path.clean_name(domain.name) + # smoke_path = '/'.join([sc_fr, smoke_filename]) + # + # with open(smoke_path, 'wb') as smoke_file: + # # Binary densitygrid file format + # # + # # File header + # smoke_file.write(b'SMOKE') #magic number + # smoke_file.write(struct.pack('<I', big_res[0])) + # smoke_file.write(struct.pack('<I', big_res[1])) + # smoke_file.write(struct.pack('<I', big_res[2])) + # Density data + # smoke_file.write(struct.pack('<%df'%len(channeldata), *channeldata)) + # + # LuxLog('Binary SMOKE file written: %s' % (smoke_path)) + + # return big_res[0], big_res[1], big_res[2], channeldata + + mydf3 = df3.df3(big_res[0], big_res[1], big_res[2]) sim_sizeX, sim_sizeY, sim_sizeZ = mydf3.size() for x in range(sim_sizeX): for y in range(sim_sizeY): for z in range(sim_sizeZ): - mydf3.set(x, y, z, channeldata[((z * sim_sizeY + y) * sim_sizeX + x)]) + mydf3.set( + x, + y, + z, + channeldata[ + ((z * sim_sizeY + y) * sim_sizeX + x) + ], + ) mydf3.exportDF3(smokePath) print('Binary smoke.df3 file written in preview directory') @@ -2055,11 +2547,16 @@ def write_pov(filename, scene=None, info_callback=None): file.write(" hollow\n") file.write(" interior{ //---------------------\n") file.write(" media{ method 3\n") - file.write(" emission <1,1,1>*1\n")# 0>1 for dark smoke to white vapour + file.write( + " emission <1,1,1>*1\n" + ) # 0>1 for dark smoke to white vapour file.write(" scattering{ 1, // Type\n") file.write(" <1,1,1>*0.1\n") file.write(" } // end scattering\n") - file.write(" density{density_file df3 \"%s\"\n" % (smokePath)) + file.write( + " density{density_file df3 \"%s\"\n" + % (smokePath) + ) file.write(" color_map {\n") file.write(" [0.00 rgb 0]\n") file.write(" [0.05 rgb 0]\n") @@ -2069,8 +2566,13 @@ def write_pov(filename, scene=None, info_callback=None): file.write(" [1.00 rgb 1]\n") file.write(" } // end color_map\n") file.write(" } // end of density\n") - file.write(" samples %i // higher = more precise\n" % resolution) - file.write(" } // end of media --------------------------\n") + file.write( + " samples %i // higher = more precise\n" + % resolution + ) + file.write( + " } // end of media --------------------------\n" + ) file.write(" } // end of interior\n") # START OF TRANSFORMATIONS @@ -2078,13 +2580,20 @@ def write_pov(filename, scene=None, info_callback=None): # Size to consider here are bbox dimensions (i.e. still in object space, *before* applying # loc/rot/scale and other transformations (like parent stuff), aka matrix_world). bbox = smoke_obj.bound_box - dim = [abs(bbox[6][0] - bbox[0][0]), abs(bbox[6][1] - bbox[0][1]), abs(bbox[6][2] - bbox[0][2])] + dim = [ + abs(bbox[6][0] - bbox[0][0]), + abs(bbox[6][1] - bbox[0][1]), + abs(bbox[6][2] - bbox[0][2]), + ] # We scale our cube to get its final size and shapes but still in *object* space (same as Blender's bbox). file.write("scale<%.6g,%.6g,%.6g>\n" % (dim[0], dim[1], dim[2])) # We offset our cube such that (0,0,0) coordinate matches Blender's object center. - file.write("translate<%.6g,%.6g,%.6g>\n" % (bbox[0][0], bbox[0][1], bbox[0][2])) + file.write( + "translate<%.6g,%.6g,%.6g>\n" + % (bbox[0][0], bbox[0][1], bbox[0][2]) + ) # We apply object's transformations to get final loc/rot/size in world space! # Note: we could combine the two previous transformations with this matrix directly... @@ -2094,30 +2603,34 @@ def write_pov(filename, scene=None, info_callback=None): file.write("}\n") - - #file.write(" interpolate 1\n") - #file.write(" frequency 0\n") - #file.write(" }\n") - #file.write("}\n") + # file.write(" interpolate 1\n") + # file.write(" frequency 0\n") + # file.write(" }\n") + # file.write("}\n") ob_num = 0 for ob in sel: - #subtract original from the count of their instances as were not counted before 2.8 + # subtract original from the count of their instances as were not counted before 2.8 if not (ob.is_instancer and ob.original != ob): ob_num += 1 # XXX I moved all those checks here, as there is no need to compute names # for object we won't export here! - if (ob.type in {'LIGHT', 'CAMERA', #'EMPTY', #empties can bear dupligroups - 'META', 'ARMATURE', 'LATTICE'}): + if ob.type in { + 'LIGHT', + 'CAMERA', #'EMPTY', #empties can bear dupligroups + 'META', + 'ARMATURE', + 'LATTICE', + }: continue - smokeFlag=False + smokeFlag = False for mod in ob.modifiers: if mod and hasattr(mod, 'smoke_type'): - smokeFlag=True - if (mod.smoke_type == 'DOMAIN'): + smokeFlag = True + if mod.smoke_type == 'DOMAIN': exportSmoke(ob.name) - break # don't render domain mesh or flow emitter mesh, skip to next object. + break # don't render domain mesh or flow emitter mesh, skip to next object. if not smokeFlag: # Export Hair renderEmitter = True @@ -2126,119 +2639,273 @@ def write_pov(filename, scene=None, info_callback=None): if ob.show_instancer_for_render: renderEmitter = True for pSys in ob.particle_systems: - for mod in [m for m in ob.modifiers if (m is not None) and (m.type == 'PARTICLE_SYSTEM')]: - if (pSys.settings.render_type == 'PATH') and mod.show_render and (pSys.name == mod.particle_system.name): + for mod in [ + m + for m in ob.modifiers + if (m is not None) + and (m.type == 'PARTICLE_SYSTEM') + ]: + if ( + (pSys.settings.render_type == 'PATH') + and mod.show_render + and (pSys.name == mod.particle_system.name) + ): tstart = time.time() - texturedHair=0 - if ob.material_slots[pSys.settings.material - 1].material and ob.active_material is not None: - pmaterial = ob.material_slots[pSys.settings.material - 1].material + texturedHair = 0 + if ( + ob.material_slots[ + pSys.settings.material - 1 + ].material + and ob.active_material is not None + ): + pmaterial = ob.material_slots[ + pSys.settings.material - 1 + ].material for th in pmaterial.texture_slots: if th and th.use: - if (th.texture.type == 'IMAGE' and th.texture.image) or th.texture.type != 'IMAGE': + if ( + ( + th.texture.type + == 'IMAGE' + and th.texture.image + ) + or th.texture.type + != 'IMAGE' + ): if th.use_map_color_diffuse: - texturedHair=1 + texturedHair = 1 if pmaterial.strand.use_blender_units: - strandStart = pmaterial.strand.root_size - strandEnd = pmaterial.strand.tip_size + strandStart = ( + pmaterial.strand.root_size + ) + strandEnd = ( + pmaterial.strand.tip_size + ) strandShape = pmaterial.strand.shape else: # Blender unit conversion - strandStart = pmaterial.strand.root_size / 200.0 - strandEnd = pmaterial.strand.tip_size / 200.0 + strandStart = ( + pmaterial.strand.root_size + / 200.0 + ) + strandEnd = ( + pmaterial.strand.tip_size + / 200.0 + ) strandShape = pmaterial.strand.shape else: - pmaterial = "default" # No material assigned in blender, use default one + pmaterial = ( + "default" + ) # No material assigned in blender, use default one strandStart = 0.01 strandEnd = 0.01 strandShape = 0.0 # Set the number of particles to render count rather than 3d view display - #pSys.set_resolution(scene, ob, 'RENDER') # DEPRECATED + # pSys.set_resolution(scene, ob, 'RENDER') # DEPRECATED # When you render, the entire dependency graph will be # evaluated at render resolution, including the particles. # In the viewport it will be at viewport resolution. # So there is no need fo render engines to use this function anymore, # it's automatic now. steps = pSys.settings.display_step - steps = 3 ** steps # or (power of 2 rather than 3) + 1 # Formerly : len(particle.hair_keys) - - totalNumberOfHairs = ( pSys.settings.count + pSys.settings.rendered_child_count ) - #hairCounter = 0 - file.write('#declare HairArray = array[%i] {\n' % totalNumberOfHairs) + steps = ( + 3 ** steps + ) # or (power of 2 rather than 3) + 1 # Formerly : len(particle.hair_keys) + + totalNumberOfHairs = ( + pSys.settings.count + + pSys.settings.rendered_child_count + ) + # hairCounter = 0 + file.write( + '#declare HairArray = array[%i] {\n' + % totalNumberOfHairs + ) for pindex in range(0, totalNumberOfHairs): - #if particle.is_exist and particle.is_visible: - #hairCounter += 1 - #controlPointCounter = 0 - # Each hair is represented as a separate sphere_sweep in POV-Ray. - - file.write('sphere_sweep{') - if pSys.settings.use_hair_bspline: - file.write('b_spline ') - file.write('%i,\n' % (steps + 2)) # +2 because the first point needs tripling to be more than a handle in POV + # if particle.is_exist and particle.is_visible: + # hairCounter += 1 + # controlPointCounter = 0 + # Each hair is represented as a separate sphere_sweep in POV-Ray. + + file.write('sphere_sweep{') + if pSys.settings.use_hair_bspline: + file.write('b_spline ') + file.write( + '%i,\n' % (steps + 2) + ) # +2 because the first point needs tripling to be more than a handle in POV + else: + file.write('linear_spline ') + file.write('%i,\n' % (steps)) + # changing world coordinates to object local coordinates by multiplying with inverted matrix + initCo = ob.matrix_world.inverted() @ ( + pSys.co_hair( + ob, particle_no=pindex, step=0 + ) + ) + if ( + ob.material_slots[ + pSys.settings.material - 1 + ].material + and ob.active_material is not None + ): + pmaterial = ob.material_slots[ + pSys.settings.material - 1 + ].material + for th in pmaterial.texture_slots: + if ( + th + and th.use + and th.use_map_color_diffuse + ): + # treat POV textures as bitmaps + if ( + th.texture.type + == 'IMAGE' + and th.texture.image + and th.texture_coords + == 'UV' + and ob.data.uv_textures + is not None + ): # or (th.texture.pov.tex_pattern_type != 'emulator' and th.texture_coords == 'UV' and ob.data.uv_textures is not None): + image = th.texture.image + image_width = image.size[ + 0 + ] + image_height = image.size[ + 1 + ] + image_pixels = image.pixels[ + : + ] + uv_co = pSys.uv_on_emitter( + mod, + pSys.particles[ + pindex + ], + pindex, + 0, + ) + x_co = round( + uv_co[0] + * (image_width - 1) + ) + y_co = round( + uv_co[1] + * (image_height - 1) + ) + pixelnumber = ( + image_width * y_co + ) + x_co + r = image_pixels[ + pixelnumber * 4 + ] + g = image_pixels[ + pixelnumber * 4 + 1 + ] + b = image_pixels[ + pixelnumber * 4 + 2 + ] + a = image_pixels[ + pixelnumber * 4 + 3 + ] + initColor = (r, g, b, a) + else: + # only overwrite variable for each competing texture for now + initColor = th.texture.evaluate( + ( + initCo[0], + initCo[1], + initCo[2], + ) + ) + for step in range(0, steps): + co = ob.matrix_world.inverted() @ ( + pSys.co_hair( + ob, + particle_no=pindex, + step=step, + ) + ) + # for controlPoint in particle.hair_keys: + if pSys.settings.clump_factor != 0: + hDiameter = ( + pSys.settings.clump_factor + / 200.0 + * random.uniform(0.5, 1) + ) + elif step == 0: + hDiameter = strandStart else: - file.write('linear_spline ') - file.write('%i,\n' % (steps)) - #changing world coordinates to object local coordinates by multiplying with inverted matrix - initCo = ob.matrix_world.inverted() @ (pSys.co_hair(ob, particle_no = pindex, step = 0)) - if ob.material_slots[pSys.settings.material - 1].material and ob.active_material is not None: - pmaterial = ob.material_slots[pSys.settings.material-1].material - for th in pmaterial.texture_slots: - if th and th.use and th.use_map_color_diffuse: - #treat POV textures as bitmaps - if (th.texture.type == 'IMAGE' and th.texture.image and th.texture_coords == 'UV' and ob.data.uv_textures is not None): # or (th.texture.pov.tex_pattern_type != 'emulator' and th.texture_coords == 'UV' and ob.data.uv_textures is not None): - image=th.texture.image - image_width = image.size[0] - image_height = image.size[1] - image_pixels = image.pixels[:] - uv_co = pSys.uv_on_emitter(mod, pSys.particles[pindex], pindex, 0) - x_co = round(uv_co[0] * (image_width - 1)) - y_co = round(uv_co[1] * (image_height - 1)) - pixelnumber = (image_width * y_co) + x_co - r = image_pixels[pixelnumber*4] - g = image_pixels[pixelnumber*4+1] - b = image_pixels[pixelnumber*4+2] - a = image_pixels[pixelnumber*4+3] - initColor=(r,g,b,a) - else: - #only overwrite variable for each competing texture for now - initColor=th.texture.evaluate((initCo[0],initCo[1],initCo[2])) - for step in range(0, steps): - co = ob.matrix_world.inverted() @ (pSys.co_hair(ob, particle_no = pindex, step = step)) - #for controlPoint in particle.hair_keys: - if pSys.settings.clump_factor != 0: - hDiameter = pSys.settings.clump_factor / 200.0 * random.uniform(0.5, 1) - elif step == 0: - hDiameter = strandStart - else: - hDiameter += (strandEnd-strandStart)/(pSys.settings.display_step+1) #XXX +1 or not? - if step == 0 and pSys.settings.use_hair_bspline: - # Write three times the first point to compensate pov Bezier handling - file.write('<%.6g,%.6g,%.6g>,%.7g,\n' % (co[0], co[1], co[2], abs(hDiameter))) - file.write('<%.6g,%.6g,%.6g>,%.7g,\n' % (co[0], co[1], co[2], abs(hDiameter))) - #file.write('<%.6g,%.6g,%.6g>,%.7g' % (particle.location[0], particle.location[1], particle.location[2], abs(hDiameter))) # Useless because particle location is the tip, not the root. - #file.write(',\n') - #controlPointCounter += 1 - #totalNumberOfHairs += len(pSys.particles)# len(particle.hair_keys) - - # Each control point is written out, along with the radius of the - # hair at that point. - file.write('<%.6g,%.6g,%.6g>,%.7g' % (co[0], co[1], co[2], abs(hDiameter))) - - # All coordinates except the last need a following comma. - - if step != steps - 1: - file.write(',\n') - else: - if texturedHair: - # Write pigment and alpha (between Pov and Blender alpha 0 and 1 are reversed) - file.write('\npigment{ color srgbf < %.3g, %.3g, %.3g, %.3g> }\n' %(initColor[0], initColor[1], initColor[2], 1.0-initColor[3])) - # End the sphere_sweep declaration for this hair - file.write('}\n') - - # All but the final sphere_sweep (each array element) needs a terminating comma. - if pindex != totalNumberOfHairs: + hDiameter += ( + strandEnd - strandStart + ) / ( + pSys.settings.display_step + + 1 + ) # XXX +1 or not? + if ( + step == 0 + and pSys.settings.use_hair_bspline + ): + # Write three times the first point to compensate pov Bezier handling + file.write( + '<%.6g,%.6g,%.6g>,%.7g,\n' + % ( + co[0], + co[1], + co[2], + abs(hDiameter), + ) + ) + file.write( + '<%.6g,%.6g,%.6g>,%.7g,\n' + % ( + co[0], + co[1], + co[2], + abs(hDiameter), + ) + ) + # file.write('<%.6g,%.6g,%.6g>,%.7g' % (particle.location[0], particle.location[1], particle.location[2], abs(hDiameter))) # Useless because particle location is the tip, not the root. + # file.write(',\n') + # controlPointCounter += 1 + # totalNumberOfHairs += len(pSys.particles)# len(particle.hair_keys) + + # Each control point is written out, along with the radius of the + # hair at that point. + file.write( + '<%.6g,%.6g,%.6g>,%.7g' + % ( + co[0], + co[1], + co[2], + abs(hDiameter), + ) + ) + + # All coordinates except the last need a following comma. + + if step != steps - 1: file.write(',\n') else: - file.write('\n') + if texturedHair: + # Write pigment and alpha (between Pov and Blender alpha 0 and 1 are reversed) + file.write( + '\npigment{ color srgbf < %.3g, %.3g, %.3g, %.3g> }\n' + % ( + initColor[0], + initColor[1], + initColor[2], + 1.0 - initColor[3], + ) + ) + # End the sphere_sweep declaration for this hair + file.write('}\n') + + # All but the final sphere_sweep (each array element) needs a terminating comma. + if pindex != totalNumberOfHairs: + file.write(',\n') + else: + file.write('\n') # End the array declaration. @@ -2249,19 +2916,39 @@ def write_pov(filename, scene=None, info_callback=None): # Pick up the hair material diffuse color and create a default POV-Ray hair texture. file.write('#ifndef (HairTexture)\n') - file.write(' #declare HairTexture = texture {\n') - file.write(' pigment {srgbt <%s,%s,%s,%s>}\n' % (pmaterial.diffuse_color[0], pmaterial.diffuse_color[1], pmaterial.diffuse_color[2], (pmaterial.strand.width_fade + 0.05))) + file.write( + ' #declare HairTexture = texture {\n' + ) + file.write( + ' pigment {srgbt <%s,%s,%s,%s>}\n' + % ( + pmaterial.diffuse_color[0], + pmaterial.diffuse_color[1], + pmaterial.diffuse_color[2], + ( + pmaterial.strand.width_fade + + 0.05 + ), + ) + ) file.write(' }\n') file.write('#end\n') file.write('\n') # Dynamically create a union of the hairstrands (or a subset of them). # By default use every hairstrand, commented line is for hand tweaking test renders. - file.write('//Increasing HairStep divides the amount of hair for test renders.\n') - file.write('#ifndef(HairStep) #declare HairStep = 1; #end\n') + file.write( + '//Increasing HairStep divides the amount of hair for test renders.\n' + ) + file.write( + '#ifndef(HairStep) #declare HairStep = 1; #end\n' + ) file.write('union{\n') file.write(' #local I = 0;\n') - file.write(' #while (I < %i)\n' % totalNumberOfHairs) + file.write( + ' #while (I < %i)\n' + % totalNumberOfHairs + ) file.write(' object {HairArray[I]') if not texturedHair: file.write(' texture{HairTexture}\n') @@ -2273,15 +2960,29 @@ def write_pov(filename, scene=None, info_callback=None): file.write(' interior {\n') file.write(' ior 1.45\n') file.write(' media {\n') - file.write(' scattering { 1, 10*<0.73, 0.35, 0.15> /*extinction 0*/ }\n') - file.write(' absorption 10/<0.83, 0.75, 0.15>\n') + file.write( + ' scattering { 1, 10*<0.73, 0.35, 0.15> /*extinction 0*/ }\n' + ) + file.write( + ' absorption 10/<0.83, 0.75, 0.15>\n' + ) file.write(' samples 1\n') file.write(' method 2\n') - file.write(' density {cylindrical\n') - file.write(' color_map {\n') - file.write(' [0.0 rgb <0.83, 0.45, 0.35>]\n') - file.write(' [0.5 rgb <0.8, 0.8, 0.4>]\n') - file.write(' [1.0 rgb <1,1,1>]\n') + file.write( + ' density {cylindrical\n' + ) + file.write( + ' color_map {\n' + ) + file.write( + ' [0.0 rgb <0.83, 0.45, 0.35>]\n' + ) + file.write( + ' [0.5 rgb <0.8, 0.8, 0.4>]\n' + ) + file.write( + ' [1.0 rgb <1,1,1>]\n' + ) file.write(' }\n') file.write(' }\n') file.write(' }\n') @@ -2293,10 +2994,15 @@ def write_pov(filename, scene=None, info_callback=None): writeMatrix(global_matrix @ ob.matrix_world) - file.write('}') - print('Totals hairstrands written: %i' % totalNumberOfHairs) - print('Number of tufts (particle systems)', len(ob.particle_systems)) + print( + 'Totals hairstrands written: %i' + % totalNumberOfHairs + ) + print( + 'Number of tufts (particle systems)', + len(ob.particle_systems), + ) # Set back the displayed number of particles to preview count # pSys.set_resolution(scene, ob, 'PREVIEW') #DEPRECATED @@ -2306,9 +3012,9 @@ def write_pov(filename, scene=None, info_callback=None): # So there is no need fo render engines to use this function anymore, # it's automatic now. if renderEmitter == False: - continue #don't render mesh, skip to next object. + continue # don't render mesh, skip to next object. - ############################################# + ############################################# # Generating a name for object just like materials to be able to use it # (baking for now or anything else). # XXX I don't understand that if we are here, sel if a non-empty iterable, @@ -2321,13 +3027,17 @@ def write_pov(filename, scene=None, info_callback=None): name_orig = "OB" + ob.name dataname_orig = "DATA" + ob.instance_collection.name else: - #hoping only dupligroups have several source datablocks - #ob_dupli_list_create(scene) #deprecated in 2.8 + # hoping only dupligroups have several source datablocks + # ob_dupli_list_create(scene) #deprecated in 2.8 depsgraph = bpy.context.evaluated_depsgraph_get() for eachduplicate in depsgraph.object_instances: - if eachduplicate.is_instance: # Real dupli instance filtered because original included in list since 2.8 - dataname_orig = "DATA" + eachduplicate.object.name - #ob.dupli_list_clear() #just don't store any reference to instance since 2.8 + if ( + eachduplicate.is_instance + ): # Real dupli instance filtered because original included in list since 2.8 + dataname_orig = ( + "DATA" + eachduplicate.object.name + ) + # ob.dupli_list_clear() #just don't store any reference to instance since 2.8 elif ob.type == 'EMPTY': name_orig = "OB" + ob.name dataname_orig = "DATA" + ob.name @@ -2335,17 +3045,22 @@ def write_pov(filename, scene=None, info_callback=None): name_orig = DEF_OBJ_NAME dataname_orig = DEF_OBJ_NAME name = string_strip_hyphen(bpy.path.clean_name(name_orig)) - dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig)) - ## for slot in ob.material_slots: - ## if slot.material is not None and slot.link == 'OBJECT': - ## obmaterial = slot.material + dataname = string_strip_hyphen( + bpy.path.clean_name(dataname_orig) + ) + ## for slot in ob.material_slots: + ## if slot.material is not None and slot.link == 'OBJECT': + ## obmaterial = slot.material - ############################################# + ############################################# if info_callback: - info_callback("Object %2.d of %2.d (%s)" % (ob_num, len(sel), ob.name)) + info_callback( + "Object %2.d of %2.d (%s)" + % (ob_num, len(sel), ob.name) + ) - #if ob.type != 'MESH': + # if ob.type != 'MESH': # continue # me = ob.data @@ -2357,92 +3072,116 @@ def write_pov(filename, scene=None, info_callback=None): print("Writing Down First Occurrence of " + name) - ############################################Povray Primitives + ############################################Povray Primitives # special exportCurves() function takes care of writing # lathe, sphere_sweep, birail, and loft except with modifiers # converted to mesh if not ob.is_modified(scene, 'RENDER'): - if ob.type == 'CURVE' and (ob.pov.curveshape in - {'lathe', 'sphere_sweep', 'loft'}): - continue #Don't render proxy mesh, skip to next object + if ob.type == 'CURVE' and ( + ob.pov.curveshape + in {'lathe', 'sphere_sweep', 'loft'} + ): + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'ISOSURFACE': - tabWrite("#declare %s = isosurface{ \n"% povdataname) + tabWrite("#declare %s = isosurface{ \n" % povdataname) tabWrite("function{ \n") textName = ob.pov.iso_function_text if textName: node_tree = bpy.context.scene.node_tree for node in node_tree.nodes: - if node.bl_idname == "IsoPropsNode" and node.label == ob.name: + if ( + node.bl_idname == "IsoPropsNode" + and node.label == ob.name + ): for inp in node.inputs: if inp: - tabWrite("#declare %s = %.6g;\n"%(inp.name,inp.default_value)) + tabWrite( + "#declare %s = %.6g;\n" + % (inp.name, inp.default_value) + ) text = bpy.data.texts[textName] for line in text.lines: split = line.body.split() if split[0] != "#declare": - tabWrite("%s\n"%line.body) + tabWrite("%s\n" % line.body) else: tabWrite("abs(x) - 2 + y") tabWrite("}\n") - tabWrite("threshold %.6g\n"%ob.pov.threshold) - tabWrite("max_gradient %.6g\n"%ob.pov.max_gradient) - tabWrite("accuracy %.6g\n"%ob.pov.accuracy) + tabWrite("threshold %.6g\n" % ob.pov.threshold) + tabWrite("max_gradient %.6g\n" % ob.pov.max_gradient) + tabWrite("accuracy %.6g\n" % ob.pov.accuracy) tabWrite("contained_by { ") if ob.pov.contained_by == "sphere": - tabWrite("sphere {0,%.6g}}\n"%ob.pov.container_scale) + tabWrite( + "sphere {0,%.6g}}\n" % ob.pov.container_scale + ) else: - tabWrite("box {-%.6g,%.6g}}\n"%(ob.pov.container_scale,ob.pov.container_scale)) + tabWrite( + "box {-%.6g,%.6g}}\n" + % ( + ob.pov.container_scale, + ob.pov.container_scale, + ) + ) if ob.pov.all_intersections: tabWrite("all_intersections\n") else: if ob.pov.max_trace > 1: - tabWrite("max_trace %.6g\n"%ob.pov.max_trace) + tabWrite("max_trace %.6g\n" % ob.pov.max_trace) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - tabWrite("scale %.6g\n"%(1/ob.pov.container_scale)) + # tabWrite("texture {%s}\n"%povMatName) + tabWrite("scale %.6g\n" % (1 / ob.pov.container_scale)) tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'SUPERELLIPSOID': - tabWrite("#declare %s = superellipsoid{ <%.4f,%.4f>\n"%(povdataname,ob.pov.se_n2,ob.pov.se_n1)) + tabWrite( + "#declare %s = superellipsoid{ <%.4f,%.4f>\n" + % (povdataname, ob.pov.se_n2, ob.pov.se_n1) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'SUPERTORUS': rMajor = ob.pov.st_major_radius rMinor = ob.pov.st_minor_radius ring = ob.pov.st_ring cross = ob.pov.st_cross - accuracy=ob.pov.st_accuracy - gradient=ob.pov.st_max_gradient + accuracy = ob.pov.st_accuracy + gradient = ob.pov.st_max_gradient ############Inline Supertorus macro - file.write("#macro Supertorus(RMj, RMn, MajorControl, MinorControl, Accuracy, MaxGradient)\n") + file.write( + "#macro Supertorus(RMj, RMn, MajorControl, MinorControl, Accuracy, MaxGradient)\n" + ) file.write(" #local CP = 2/MinorControl;\n") file.write(" #local RP = 2/MajorControl;\n") file.write(" isosurface {\n") - file.write(" function { pow( pow(abs(pow(pow(abs(x),RP) + pow(abs(z),RP), 1/RP) - RMj),CP) + pow(abs(y),CP) ,1/CP) - RMn }\n") + file.write( + " function { pow( pow(abs(pow(pow(abs(x),RP) + pow(abs(z),RP), 1/RP) - RMj),CP) + pow(abs(y),CP) ,1/CP) - RMn }\n" + ) file.write(" threshold 0\n") - file.write(" contained_by {box {<-RMj-RMn,-RMn,-RMj-RMn>, < RMj+RMn, RMn, RMj+RMn>}}\n") + file.write( + " contained_by {box {<-RMj-RMn,-RMn,-RMj-RMn>, < RMj+RMn, RMn, RMj+RMn>}}\n" + ) file.write(" #if(MaxGradient >= 1)\n") file.write(" max_gradient MaxGradient\n") file.write(" #else\n") @@ -2452,229 +3191,286 @@ def write_pov(filename, scene=None, info_callback=None): file.write(" }\n") file.write("#end\n") ############ - tabWrite("#declare %s = object{ Supertorus( %.4g,%.4g,%.4g,%.4g,%.4g,%.4g)\n"%(povdataname,rMajor,rMinor,ring,cross,accuracy,gradient)) + tabWrite( + "#declare %s = object{ Supertorus( %.4g,%.4g,%.4g,%.4g,%.4g,%.4g)\n" + % ( + povdataname, + rMajor, + rMinor, + ring, + cross, + accuracy, + gradient, + ) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'PLANE': - tabWrite("#declare %s = plane{ <0,0,1>,1\n"%povdataname) + tabWrite( + "#declare %s = plane{ <0,0,1>,1\n" % povdataname + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'BOX': - tabWrite("#declare %s = box { -1,1\n"%povdataname) + tabWrite("#declare %s = box { -1,1\n" % povdataname) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'CONE': br = ob.pov.cone_base_radius cr = ob.pov.cone_cap_radius bz = ob.pov.cone_base_z cz = ob.pov.cone_cap_z - tabWrite("#declare %s = cone { <0,0,%.4f>,%.4f,<0,0,%.4f>,%.4f\n"%(povdataname,bz,br,cz,cr)) + tabWrite( + "#declare %s = cone { <0,0,%.4f>,%.4f,<0,0,%.4f>,%.4f\n" + % (povdataname, bz, br, cz, cr) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'CYLINDER': r = ob.pov.cylinder_radius x2 = ob.pov.cylinder_location_cap[0] y2 = ob.pov.cylinder_location_cap[1] z2 = ob.pov.cylinder_location_cap[2] - tabWrite("#declare %s = cylinder { <0,0,0>,<%6f,%6f,%6f>,%6f\n"%( - povdataname, - x2, - y2, - z2, - r)) + tabWrite( + "#declare %s = cylinder { <0,0,0>,<%6f,%6f,%6f>,%6f\n" + % (povdataname, x2, y2, z2, r) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - #cylinders written at origin, translated below - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") + # tabWrite("texture {%s}\n"%povMatName) + # cylinders written at origin, translated below + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'HEIGHT_FIELD': data = "" filename = ob.pov.hf_filename - data += '"%s"'%filename - gamma = ' gamma %.4f'%ob.pov.hf_gamma + data += '"%s"' % filename + gamma = ' gamma %.4f' % ob.pov.hf_gamma data += gamma if ob.pov.hf_premultiplied: data += ' premultiplied on' if ob.pov.hf_smooth: data += ' smooth' if ob.pov.hf_water > 0: - data += ' water_level %.4f'%ob.pov.hf_water - #hierarchy = ob.pov.hf_hierarchy - tabWrite('#declare %s = height_field { %s\n'%(povdataname,data)) + data += ' water_level %.4f' % ob.pov.hf_water + # hierarchy = ob.pov.hf_hierarchy + tabWrite( + '#declare %s = height_field { %s\n' + % (povdataname, data) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) tabWrite("rotate x*90\n") tabWrite("translate <-0.5,0.5,0>\n") tabWrite("scale <0,-1,0>\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'SPHERE': - tabWrite("#declare %s = sphere { 0,%6f\n"%(povdataname,ob.pov.sphere_radius)) + tabWrite( + "#declare %s = sphere { 0,%6f\n" + % (povdataname, ob.pov.sphere_radius) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) - #tabWrite("rotate x*90\n") + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) + # tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'TORUS': - tabWrite("#declare %s = torus { %.4f,%.4f\n"%(povdataname,ob.pov.torus_major_radius,ob.pov.torus_minor_radius)) + tabWrite( + "#declare %s = torus { %.4f,%.4f\n" + % ( + povdataname, + ob.pov.torus_major_radius, + ob.pov.torus_minor_radius, + ) + ) povMatName = "Default_texture" if ob.active_material: - #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) + # povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name)) try: material = ob.active_material writeObjectMaterial(material, ob) except IndexError: print(me) - #tabWrite("texture {%s}\n"%povMatName) - write_object_modifiers(scene,ob,file) + # tabWrite("texture {%s}\n"%povMatName) + write_object_modifiers(scene, ob, file) tabWrite("rotate x*90\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'PARAMETRIC': - tabWrite("#declare %s = parametric {\n"%povdataname) - tabWrite("function { %s }\n"%ob.pov.x_eq) - tabWrite("function { %s }\n"%ob.pov.y_eq) - tabWrite("function { %s }\n"%ob.pov.z_eq) - tabWrite("<%.4f,%.4f>, <%.4f,%.4f>\n"%(ob.pov.u_min,ob.pov.v_min,ob.pov.u_max,ob.pov.v_max)) + tabWrite("#declare %s = parametric {\n" % povdataname) + tabWrite("function { %s }\n" % ob.pov.x_eq) + tabWrite("function { %s }\n" % ob.pov.y_eq) + tabWrite("function { %s }\n" % ob.pov.z_eq) + tabWrite( + "<%.4f,%.4f>, <%.4f,%.4f>\n" + % ( + ob.pov.u_min, + ob.pov.v_min, + ob.pov.u_max, + ob.pov.v_max, + ) + ) if ob.pov.contained_by == "sphere": tabWrite("contained_by { sphere{0, 2} }\n") else: tabWrite("contained_by { box{-2, 2} }\n") - tabWrite("max_gradient %.6f\n"%ob.pov.max_gradient) - tabWrite("accuracy %.6f\n"%ob.pov.accuracy) + tabWrite("max_gradient %.6f\n" % ob.pov.max_gradient) + tabWrite("accuracy %.6f\n" % ob.pov.accuracy) tabWrite("precompute 10 x,y,z\n") tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object + continue # Don't render proxy mesh, skip to next object if ob.pov.object_as == 'POLYCIRCLE': - #TODO write below macro Once: - #if write_polytocircle_macro_once == 0: + # TODO write below macro Once: + # if write_polytocircle_macro_once == 0: file.write("/****************************\n") file.write("This macro was written by 'And'.\n") - file.write("Link:(http://news.povray.org/povray.binaries.scene-files/)\n") + file.write( + "Link:(http://news.povray.org/povray.binaries.scene-files/)\n" + ) file.write("****************************/\n") file.write("//from math.inc:\n") file.write("#macro VPerp_Adjust(V, Axis)\n") - file.write(" vnormalize(vcross(vcross(Axis, V), Axis))\n") + file.write( + " vnormalize(vcross(vcross(Axis, V), Axis))\n" + ) file.write("#end\n") file.write("//Then for the actual macro\n") - file.write("#macro Shape_Slice_Plane_2P_1V(point1, point2, clip_direct)\n") + file.write( + "#macro Shape_Slice_Plane_2P_1V(point1, point2, clip_direct)\n" + ) file.write("#local p1 = point1 + <0,0,0>;\n") file.write("#local p2 = point2 + <0,0,0>;\n") - file.write("#local clip_v = vnormalize(clip_direct + <0,0,0>);\n") + file.write( + "#local clip_v = vnormalize(clip_direct + <0,0,0>);\n" + ) file.write("#local direct_v1 = vnormalize(p2 - p1);\n") file.write("#if(vdot(direct_v1, clip_v) = 1)\n") - file.write(' #error "Shape_Slice_Plane_2P_1V error: Can\'t decide plane"\n') + file.write( + ' #error "Shape_Slice_Plane_2P_1V error: Can\'t decide plane"\n' + ) file.write("#end\n\n") - file.write("#local norm = -vnormalize(clip_v - direct_v1*vdot(direct_v1,clip_v));\n") + file.write( + "#local norm = -vnormalize(clip_v - direct_v1*vdot(direct_v1,clip_v));\n" + ) file.write("#local d = vdot(norm, p1);\n") file.write("plane{\n") file.write("norm, d\n") file.write("}\n") file.write("#end\n\n") file.write("//polygon to circle\n") - file.write("#macro Shape_Polygon_To_Circle_Blending(_polygon_n, _side_face, _polygon_circumscribed_radius, _circle_radius, _height)\n") + file.write( + "#macro Shape_Polygon_To_Circle_Blending(_polygon_n, _side_face, _polygon_circumscribed_radius, _circle_radius, _height)\n" + ) file.write("#local n = int(_polygon_n);\n") file.write("#if(n < 3)\n") - file.write(" #error ""\n") + file.write(" #error " "\n") file.write("#end\n\n") - file.write("#local front_v = VPerp_Adjust(_side_face, z);\n") + file.write( + "#local front_v = VPerp_Adjust(_side_face, z);\n" + ) file.write("#if(vdot(front_v, x) >= 0)\n") - file.write(" #local face_ang = acos(vdot(-y, front_v));\n") + file.write( + " #local face_ang = acos(vdot(-y, front_v));\n" + ) file.write("#else\n") - file.write(" #local face_ang = -acos(vdot(-y, front_v));\n") + file.write( + " #local face_ang = -acos(vdot(-y, front_v));\n" + ) file.write("#end\n") file.write("#local polyg_ext_ang = 2*pi/n;\n") - file.write("#local polyg_outer_r = _polygon_circumscribed_radius;\n") - file.write("#local polyg_inner_r = polyg_outer_r*cos(polyg_ext_ang/2);\n") + file.write( + "#local polyg_outer_r = _polygon_circumscribed_radius;\n" + ) + file.write( + "#local polyg_inner_r = polyg_outer_r*cos(polyg_ext_ang/2);\n" + ) file.write("#local cycle_r = _circle_radius;\n") file.write("#local h = _height;\n") - file.write("#if(polyg_outer_r < 0 | cycle_r < 0 | h <= 0)\n") - file.write(' #error "error: each side length must be positive"\n') + file.write( + "#if(polyg_outer_r < 0 | cycle_r < 0 | h <= 0)\n" + ) + file.write( + ' #error "error: each side length must be positive"\n' + ) file.write("#end\n\n") file.write("#local multi = 1000;\n") file.write("#local poly_obj =\n") @@ -2682,29 +3478,47 @@ def write_pov(filename, scene=None, info_callback=None): file.write("4,\n") file.write("xyz(0,2,2): multi*1,\n") file.write("xyz(2,0,1): multi*2*h,\n") - file.write("xyz(1,0,2): multi*2*(polyg_inner_r-cycle_r),\n") + file.write( + "xyz(1,0,2): multi*2*(polyg_inner_r-cycle_r),\n" + ) file.write("xyz(2,0,0): multi*(-h*h),\n") - file.write("xyz(0,0,2): multi*(-pow(cycle_r - polyg_inner_r, 2)),\n") - file.write("xyz(1,0,1): multi*2*h*(-2*polyg_inner_r + cycle_r),\n") + file.write( + "xyz(0,0,2): multi*(-pow(cycle_r - polyg_inner_r, 2)),\n" + ) + file.write( + "xyz(1,0,1): multi*2*h*(-2*polyg_inner_r + cycle_r),\n" + ) file.write("xyz(1,0,0): multi*2*h*h*polyg_inner_r,\n") - file.write("xyz(0,0,1): multi*2*h*polyg_inner_r*(polyg_inner_r - cycle_r),\n") - file.write("xyz(0,0,0): multi*(-pow(polyg_inner_r*h, 2))\n") + file.write( + "xyz(0,0,1): multi*2*h*polyg_inner_r*(polyg_inner_r - cycle_r),\n" + ) + file.write( + "xyz(0,0,0): multi*(-pow(polyg_inner_r*h, 2))\n" + ) file.write("sturm\n") file.write("}\n\n") file.write("#local mockup1 =\n") file.write("difference{\n") file.write(" cylinder{\n") - file.write(" <0,0,0.0>,<0,0,h>, max(polyg_outer_r, cycle_r)\n") + file.write( + " <0,0,0.0>,<0,0,h>, max(polyg_outer_r, cycle_r)\n" + ) file.write(" }\n\n") file.write(" #for(i, 0, n-1)\n") file.write(" object{\n") file.write(" poly_obj\n") file.write(" inverse\n") - file.write(" rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n") + file.write( + " rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n" + ) file.write(" }\n") file.write(" object{\n") - file.write(" Shape_Slice_Plane_2P_1V(<polyg_inner_r,0,0>,<cycle_r,0,h>,x)\n") - file.write(" rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n") + file.write( + " Shape_Slice_Plane_2P_1V(<polyg_inner_r,0,0>,<cycle_r,0,h>,x)\n" + ) + file.write( + " rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n" + ) file.write(" }\n") file.write(" #end\n") file.write("}\n\n") @@ -2713,20 +3527,29 @@ def write_pov(filename, scene=None, info_callback=None): file.write("rotate <0, 0, degrees(face_ang)>\n") file.write("}\n") file.write("#end\n") - #Use the macro + # Use the macro ngon = ob.pov.polytocircle_ngon ngonR = ob.pov.polytocircle_ngonR circleR = ob.pov.polytocircle_circleR - tabWrite("#declare %s = object { Shape_Polygon_To_Circle_Blending(%s, z, %.4f, %.4f, 2) rotate x*180 translate z*1\n"%(povdataname,ngon,ngonR,circleR)) + tabWrite( + "#declare %s = object { Shape_Polygon_To_Circle_Blending(%s, z, %.4f, %.4f, 2) rotate x*180 translate z*1\n" + % (povdataname, ngon, ngonR, circleR) + ) tabWrite("}\n") - continue #Don't render proxy mesh, skip to next object - + continue # Don't render proxy mesh, skip to next object - ############################################else try to export mesh - elif ob.is_instancer == False: #except duplis which should be instances groups for now but all duplis later + ############################################else try to export mesh + elif ( + ob.is_instancer == False + ): # except duplis which should be instances groups for now but all duplis later if ob.type == 'EMPTY': - tabWrite("\n//dummy sphere to represent Empty location\n") - tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname) + tabWrite( + "\n//dummy sphere to represent Empty location\n" + ) + tabWrite( + "#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" + % povdataname + ) # TODO(sergey): PovRay is a render engine, so should be using dependency graph # which was given to it via render engine API. @@ -2735,8 +3558,8 @@ def write_pov(filename, scene=None, info_callback=None): try: me = ob_eval.to_mesh() - #XXX Here? identify the specific exception for mesh object with no data - #XXX So that we can write something for the dataname ! + # XXX Here? identify the specific exception for mesh object with no data + # XXX So that we can write something for the dataname ! except: # also happens when curves cant be made into meshes because of no-data @@ -2747,14 +3570,18 @@ def write_pov(filename, scene=None, info_callback=None): me.calc_loop_triangles() me_materials = me.materials me_faces = me.loop_triangles[:] - #if len(me_faces)==0: - #tabWrite("\n//dummy sphere to represent empty mesh location\n") - #tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname) - + # if len(me_faces)==0: + # tabWrite("\n//dummy sphere to represent empty mesh location\n") + # tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname) if not me or not me_faces: - tabWrite("\n//dummy sphere to represent empty mesh location\n") - tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname) + tabWrite( + "\n//dummy sphere to represent empty mesh location\n" + ) + tabWrite( + "#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" + % povdataname + ) continue uv_layers = me.uv_layers @@ -2765,7 +3592,7 @@ def write_pov(filename, scene=None, info_callback=None): uv_layer = None try: - #vcol_layer = me.vertex_colors.active.data + # vcol_layer = me.vertex_colors.active.data vcol_layer = me.vertex_colors.active.data except AttributeError: vcol_layer = None @@ -2785,11 +3612,15 @@ def write_pov(filename, scene=None, info_callback=None): for v in me.vertices: if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%.6f, %.6f, %.6f>" % v.co[:]) # vert count + file.write( + tabStr + "<%.6f, %.6f, %.6f>" % v.co[:] + ) # vert count else: file.write(", ") - file.write("<%.6f, %.6f, %.6f>" % v.co[:]) # vert count - #tabWrite("<%.6f, %.6f, %.6f>" % v.co[:]) # vert count + file.write( + "<%.6f, %.6f, %.6f>" % v.co[:] + ) # vert count + # tabWrite("<%.6f, %.6f, %.6f>" % v.co[:]) # vert count file.write("\n") tabWrite("}\n") @@ -2813,10 +3644,14 @@ def write_pov(filename, scene=None, info_callback=None): for no, index in uniqueNormals.items(): if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%.6f, %.6f, %.6f>" % no) # vert count + file.write( + tabStr + "<%.6f, %.6f, %.6f>" % no + ) # vert count else: file.write(", ") - file.write("<%.6f, %.6f, %.6f>" % no) # vert count + file.write( + "<%.6f, %.6f, %.6f>" % no + ) # vert count index[0] = idx idx += 1 file.write("\n") @@ -2828,15 +3663,15 @@ def write_pov(filename, scene=None, info_callback=None): if uv_layer: # Generate unique UV's uniqueUVs = {} - #n = 0 - for f in me_faces: # me.faces in 2.7 + # n = 0 + for f in me_faces: # me.faces in 2.7 uvs = [uv_layer[l].uv[:] for l in f.loops] for uv in uvs: uniqueUVs[uv[:]] = [-1] tabWrite("uv_vectors {\n") - #print unique_uvs + # print unique_uvs tabWrite("%d" % len(uniqueUVs)) # vert count idx = 0 tabStr = tab * tabLevel @@ -2859,12 +3694,16 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("}\n") if me.vertex_colors: - #Write down vertex colors as a texture for each vertex + # Write down vertex colors as a texture for each vertex tabWrite("texture_list {\n") - tabWrite("%d\n" % (len(me_faces) * 3)) # assumes we have only triangles - VcolIdx=0 + tabWrite( + "%d\n" % (len(me_faces) * 3) + ) # assumes we have only triangles + VcolIdx = 0 if comments: - file.write("\n //Vertex colors: one simple pigment texture per vertex\n") + file.write( + "\n //Vertex colors: one simple pigment texture per vertex\n" + ) for fi, f in enumerate(me_faces): # annoying, index may be invalid material_index = f.material_index @@ -2872,31 +3711,66 @@ def write_pov(filename, scene=None, info_callback=None): material = me_materials[material_index] except: material = None - if material: #and material.use_vertex_color_paint: #Always use vertex color when there is some for now + if ( + material + ): # and material.use_vertex_color_paint: #Always use vertex color when there is some for now - cols = [vcol_layer[l].color[:] for l in f.loops] + cols = [ + vcol_layer[l].color[:] for l in f.loops + ] for col in cols: - key = col[0], col[1], col[2], material_index # Material index! - VcolIdx+=1 + key = ( + col[0], + col[1], + col[2], + material_index, + ) # Material index! + VcolIdx += 1 vertCols[key] = [VcolIdx] if linebreaksinlists: - tabWrite("texture {pigment{ color srgb <%6f,%6f,%6f> }}\n" % (col[0], col[1], col[2])) + tabWrite( + "texture {pigment{ color srgb <%6f,%6f,%6f> }}\n" + % (col[0], col[1], col[2]) + ) else: - tabWrite("texture {pigment{ color srgb <%6f,%6f,%6f> }}" % (col[0], col[1], col[2])) + tabWrite( + "texture {pigment{ color srgb <%6f,%6f,%6f> }}" + % (col[0], col[1], col[2]) + ) tabStr = tab * tabLevel else: if material: # Multiply diffuse with SSS Color - if material.pov_subsurface_scattering.use: - diffuse_color = [i * j for i, j in zip(material.pov_subsurface_scattering.color[:], material.diffuse_color[:])] - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], \ - material_index + if ( + material.pov_subsurface_scattering.use + ): + diffuse_color = [ + i * j + for i, j in zip( + material.pov_subsurface_scattering.color[ + : + ], + material.diffuse_color[:], + ) + ] + key = ( + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + material_index, + ) vertCols[key] = [-1] else: - diffuse_color = material.diffuse_color[:] - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], \ - material_index + diffuse_color = material.diffuse_color[ + : + ] + key = ( + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + material_index, + ) vertCols[key] = [-1] tabWrite("\n}\n") @@ -2910,45 +3784,108 @@ def write_pov(filename, scene=None, info_callback=None): material_index = f.material_index if vcol_layer: - cols = [vcol_layer[l].color[:] for l in f.loops] - - if not me_materials or me_materials[material_index] is None: # No materials + cols = [ + vcol_layer[l].color[:] for l in f.loops + ] + + if ( + not me_materials + or me_materials[material_index] is None + ): # No materials if linebreaksinlists: file.write(",\n") # vert count - file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2])) + file.write( + tabStr + + "<%d,%d,%d>" + % (fv[0], fv[1], fv[2]) + ) else: file.write(", ") - file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2])) # vert count + file.write( + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]) + ) # vert count else: material = me_materials[material_index] - if me.vertex_colors: #and material.use_vertex_color_paint: + if ( + me.vertex_colors + ): # and material.use_vertex_color_paint: # Color per vertex - vertex color col1 = cols[0] col2 = cols[1] col3 = cols[2] - ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0] - ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0] - ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0] + ci1 = vertCols[ + col1[0], + col1[1], + col1[2], + material_index, + ][0] + ci2 = vertCols[ + col2[0], + col2[1], + col2[2], + material_index, + ][0] + ci3 = vertCols[ + col3[0], + col3[1], + col3[2], + material_index, + ][0] else: # Color per material - flat material color - if material.pov_subsurface_scattering.use: - diffuse_color = [i * j for i, j in zip(material.pov_subsurface_scattering.color[:], material.diffuse_color[:])] + if ( + material.pov_subsurface_scattering.use + ): + diffuse_color = [ + i * j + for i, j in zip( + material.pov_subsurface_scattering.color[ + : + ], + material.diffuse_color[:], + ) + ] else: - diffuse_color = material.diffuse_color[:] - ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \ - diffuse_color[2], f.material_index][0] + diffuse_color = material.diffuse_color[ + : + ] + ci1 = ci2 = ci3 = vertCols[ + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + f.material_index, + ][0] # ci are zero based index so we'll subtract 1 from them if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \ - (fv[0], fv[1], fv[2], ci1-1, ci2-1, ci3-1)) # vert count + file.write( + tabStr + + "<%d,%d,%d>, %d,%d,%d" + % ( + fv[0], + fv[1], + fv[2], + ci1 - 1, + ci2 - 1, + ci3 - 1, + ) + ) # vert count else: file.write(", ") - file.write("<%d,%d,%d>, %d,%d,%d" % \ - (fv[0], fv[1], fv[2], ci1-1, ci2-1, ci3-1)) # vert count + file.write( + "<%d,%d,%d>, %d,%d,%d" + % ( + fv[0], + fv[1], + fv[2], + ci1 - 1, + ci2 - 1, + ci3 - 1, + ) + ) # vert count file.write("\n") tabWrite("}\n") @@ -2962,24 +3899,50 @@ def write_pov(filename, scene=None, info_callback=None): if me_faces[fi].use_smooth: if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" %\ - (uniqueNormals[verts_normals[fv[0]]][0],\ - uniqueNormals[verts_normals[fv[1]]][0],\ - uniqueNormals[verts_normals[fv[2]]][0])) # vert count + file.write( + tabStr + + "<%d,%d,%d>" + % ( + uniqueNormals[ + verts_normals[fv[0]] + ][0], + uniqueNormals[ + verts_normals[fv[1]] + ][0], + uniqueNormals[ + verts_normals[fv[2]] + ][0], + ) + ) # vert count else: file.write(", ") - file.write("<%d,%d,%d>" %\ - (uniqueNormals[verts_normals[fv[0]]][0],\ - uniqueNormals[verts_normals[fv[1]]][0],\ - uniqueNormals[verts_normals[fv[2]]][0])) # vert count + file.write( + "<%d,%d,%d>" + % ( + uniqueNormals[ + verts_normals[fv[0]] + ][0], + uniqueNormals[ + verts_normals[fv[1]] + ][0], + uniqueNormals[ + verts_normals[fv[2]] + ][0], + ) + ) # vert count else: idx = uniqueNormals[faces_normals[fi]][0] if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vert count + file.write( + tabStr + + "<%d,%d,%d>" % (idx, idx, idx) + ) # vert count else: file.write(", ") - file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count + file.write( + "<%d,%d,%d>" % (idx, idx, idx) + ) # vert count file.write("\n") tabWrite("}\n") @@ -2993,31 +3956,44 @@ def write_pov(filename, scene=None, info_callback=None): if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" % ( - uniqueUVs[uvs[0]][0],\ - uniqueUVs[uvs[1]][0],\ - uniqueUVs[uvs[2]][0])) + file.write( + tabStr + + "<%d,%d,%d>" + % ( + uniqueUVs[uvs[0]][0], + uniqueUVs[uvs[1]][0], + uniqueUVs[uvs[2]][0], + ) + ) else: file.write(", ") - file.write("<%d,%d,%d>" % ( - uniqueUVs[uvs[0]][0],\ - uniqueUVs[uvs[1]][0],\ - uniqueUVs[uvs[2]][0])) + file.write( + "<%d,%d,%d>" + % ( + uniqueUVs[uvs[0]][0], + uniqueUVs[uvs[1]][0], + uniqueUVs[uvs[2]][0], + ) + ) file.write("\n") tabWrite("}\n") - #XXX BOOLEAN + # XXX BOOLEAN onceCSG = 0 for mod in ob.modifiers: if onceCSG == 0: - if mod : + if mod: if mod.type == 'BOOLEAN': if ob.pov.boolean_mod == "POV": - file.write("\tinside_vector <%.6g, %.6g, %.6g>\n" % - (ob.pov.inside_vector[0], - ob.pov.inside_vector[1], - ob.pov.inside_vector[2])) + file.write( + "\tinside_vector <%.6g, %.6g, %.6g>\n" + % ( + ob.pov.inside_vector[0], + ob.pov.inside_vector[1], + ob.pov.inside_vector[2], + ) + ) onceCSG = 1 if me.materials: @@ -3029,16 +4005,16 @@ def write_pov(filename, scene=None, info_callback=None): # POV object modifiers such as # hollow / sturm / double_illuminate etc. - write_object_modifiers(scene,ob,file) + write_object_modifiers(scene, ob, file) - #Importance for radiosity sampling added here: + # Importance for radiosity sampling added here: tabWrite("radiosity { \n") tabWrite("importance %3g \n" % importance) tabWrite("}\n") tabWrite("}\n") # End of mesh block else: - facesMaterials = [] # WARNING!!!!!!!!!!!!!!!!!!!!!! + facesMaterials = [] # WARNING!!!!!!!!!!!!!!!!!!!!!! if me_materials: for f in me_faces: if f.material_index not in facesMaterials: @@ -3046,78 +4022,125 @@ def write_pov(filename, scene=None, info_callback=None): # No vertex colors, so write material colors as vertex colors for i, material in enumerate(me_materials): - if material and material.pov.material_use_nodes == False: # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if ( + material + and material.pov.material_use_nodes == False + ): # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # Multiply diffuse with SSS Color if material.pov_subsurface_scattering.use: - diffuse_color = [i * j for i, j in zip(material.pov_subsurface_scattering.color[:], material.diffuse_color[:])] - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat + diffuse_color = [ + i * j + for i, j in zip( + material.pov_subsurface_scattering.color[ + : + ], + material.diffuse_color[:], + ) + ] + key = ( + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + i, + ) # i == f.mat vertCols[key] = [-1] else: - diffuse_color = material.diffuse_color[:] - key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat + diffuse_color = material.diffuse_color[ + : + ] + key = ( + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + i, + ) # i == f.mat vertCols[key] = [-1] idx = 0 LocalMaterialNames = [] for col, index in vertCols.items(): - #if me_materials: + # if me_materials: mater = me_materials[col[3]] - if me_materials is None: #XXX working? - material_finish = DEF_MAT_NAME # not working properly, + if me_materials is None: # XXX working? + material_finish = ( + DEF_MAT_NAME + ) # not working properly, trans = 0.0 else: - shading.writeTextureInfluence(mater, materialNames, - LocalMaterialNames, - path_image, lampCount, - imageFormat, imgMap, - imgMapTransforms, - tabWrite, comments, - string_strip_hyphen, - safety, col, os, preview_dir, unpacked_images) + shading.writeTextureInfluence( + mater, + materialNames, + LocalMaterialNames, + path_image, + lampCount, + imageFormat, + imgMap, + imgMapTransforms, + tabWrite, + comments, + string_strip_hyphen, + safety, + col, + os, + preview_dir, + unpacked_images, + ) ################################################################### index[0] = idx idx += 1 - - # Vert Colors tabWrite("texture_list {\n") # In case there's is no material slot, give at least one texture - #(an empty one so it uses pov default) - if len(vertCols)==0: + # (an empty one so it uses pov default) + if len(vertCols) == 0: file.write(tabStr + "1") else: - file.write(tabStr + "%s" % (len(vertCols))) # vert count - - - + file.write( + tabStr + "%s" % (len(vertCols)) + ) # vert count # below "material" alias, added check ob.active_material # to avoid variable referenced before assignment error try: material = ob.active_material except IndexError: - #when no material slot exists, - material=None + # when no material slot exists, + material = None # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if material and ob.active_material is not None and material.pov.material_use_nodes == False: + if ( + material + and ob.active_material is not None + and material.pov.material_use_nodes == False + ): if material.pov.replacement_text != "": file.write("\n") - file.write(" texture{%s}\n" % material.pov.replacement_text) + 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) - #use string_strip_hyphen(materialNames[material])) - #or Something like that to clean up the above? + file.write( + "\n texture{MAT_%s}\n" % cMN + ) + # use string_strip_hyphen(materialNames[material])) + # or Something like that to clean up the above? elif material and material.pov.material_use_nodes: for index in facesMaterials: - faceMaterial = string_strip_hyphen(bpy.path.clean_name(me_materials[index].name)) - file.write("\n texture{%s}\n" % faceMaterial) + faceMaterial = string_strip_hyphen( + bpy.path.clean_name( + me_materials[index].name + ) + ) + file.write( + "\n texture{%s}\n" % faceMaterial + ) # END!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! else: file.write(" texture{}\n") @@ -3133,50 +4156,111 @@ def write_pov(filename, scene=None, info_callback=None): material_index = f.material_index if vcol_layer: - cols = [vcol_layer[l].color[:] for l in f.loops] - - if not me_materials or me_materials[material_index] is None: # No materials + cols = [ + vcol_layer[l].color[:] for l in f.loops + ] + + if ( + not me_materials + or me_materials[material_index] is None + ): # No materials if linebreaksinlists: file.write(",\n") # vert count - file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2])) + file.write( + tabStr + + "<%d,%d,%d>" + % (fv[0], fv[1], fv[2]) + ) else: file.write(", ") - file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2])) # vert count + file.write( + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]) + ) # vert count else: material = me_materials[material_index] ci1 = ci2 = ci3 = f.material_index - if me.vertex_colors: #and material.use_vertex_color_paint: + if ( + me.vertex_colors + ): # and material.use_vertex_color_paint: # Color per vertex - vertex color col1 = cols[0] col2 = cols[1] col3 = cols[2] - ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0] - ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0] - ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0] + ci1 = vertCols[ + col1[0], + col1[1], + col1[2], + material_index, + ][0] + ci2 = vertCols[ + col2[0], + col2[1], + col2[2], + material_index, + ][0] + ci3 = vertCols[ + col3[0], + col3[1], + col3[2], + material_index, + ][0] elif material.pov.material_use_nodes: ci1 = ci2 = ci3 = 0 else: # Color per material - flat material color - if material.pov_subsurface_scattering.use: - diffuse_color = [i * j for i, j in - zip(material.pov_subsurface_scattering.color[:], - material.diffuse_color[:])] + if ( + material.pov_subsurface_scattering.use + ): + diffuse_color = [ + i * j + for i, j in zip( + material.pov_subsurface_scattering.color[ + : + ], + material.diffuse_color[:], + ) + ] else: - diffuse_color = material.diffuse_color[:] - ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \ - diffuse_color[2], f.material_index][0] + diffuse_color = material.diffuse_color[ + : + ] + ci1 = ci2 = ci3 = vertCols[ + diffuse_color[0], + diffuse_color[1], + diffuse_color[2], + f.material_index, + ][0] if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \ - (fv[0], fv[1], fv[2], ci1, ci2, ci3)) # vert count + file.write( + tabStr + + "<%d,%d,%d>, %d,%d,%d" + % ( + fv[0], + fv[1], + fv[2], + ci1, + ci2, + ci3, + ) + ) # vert count else: file.write(", ") - file.write("<%d,%d,%d>, %d,%d,%d" % \ - (fv[0], fv[1], fv[2], ci1, ci2, ci3)) # vert count + file.write( + "<%d,%d,%d>, %d,%d,%d" + % ( + fv[0], + fv[1], + fv[2], + ci1, + ci2, + ci3, + ) + ) # vert count file.write("\n") tabWrite("}\n") @@ -3189,24 +4273,50 @@ def write_pov(filename, scene=None, info_callback=None): if me_faces[fi].use_smooth: if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" %\ - (uniqueNormals[verts_normals[fv[0]]][0],\ - uniqueNormals[verts_normals[fv[1]]][0],\ - uniqueNormals[verts_normals[fv[2]]][0])) # vert count + file.write( + tabStr + + "<%d,%d,%d>" + % ( + uniqueNormals[ + verts_normals[fv[0]] + ][0], + uniqueNormals[ + verts_normals[fv[1]] + ][0], + uniqueNormals[ + verts_normals[fv[2]] + ][0], + ) + ) # vert count else: file.write(", ") - file.write("<%d,%d,%d>" %\ - (uniqueNormals[verts_normals[fv[0]]][0],\ - uniqueNormals[verts_normals[fv[1]]][0],\ - uniqueNormals[verts_normals[fv[2]]][0])) # vert count + file.write( + "<%d,%d,%d>" + % ( + uniqueNormals[ + verts_normals[fv[0]] + ][0], + uniqueNormals[ + verts_normals[fv[1]] + ][0], + uniqueNormals[ + verts_normals[fv[2]] + ][0], + ) + ) # vert count else: idx = uniqueNormals[faces_normals[fi]][0] if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vertcount + file.write( + tabStr + + "<%d,%d,%d>" % (idx, idx, idx) + ) # vertcount else: file.write(", ") - file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count + file.write( + "<%d,%d,%d>" % (idx, idx, idx) + ) # vert count file.write("\n") tabWrite("}\n") @@ -3220,31 +4330,44 @@ def write_pov(filename, scene=None, info_callback=None): if linebreaksinlists: file.write(",\n") - file.write(tabStr + "<%d,%d,%d>" % ( - uniqueUVs[uvs[0]][0],\ - uniqueUVs[uvs[1]][0],\ - uniqueUVs[uvs[2]][0])) + file.write( + tabStr + + "<%d,%d,%d>" + % ( + uniqueUVs[uvs[0]][0], + uniqueUVs[uvs[1]][0], + uniqueUVs[uvs[2]][0], + ) + ) else: file.write(", ") - file.write("<%d,%d,%d>" % ( - uniqueUVs[uvs[0]][0],\ - uniqueUVs[uvs[1]][0],\ - uniqueUVs[uvs[2]][0])) + file.write( + "<%d,%d,%d>" + % ( + uniqueUVs[uvs[0]][0], + uniqueUVs[uvs[1]][0], + uniqueUVs[uvs[2]][0], + ) + ) file.write("\n") tabWrite("}\n") - #XXX BOOLEAN + # XXX BOOLEAN onceCSG = 0 for mod in ob.modifiers: if onceCSG == 0: - if mod : + if mod: if mod.type == 'BOOLEAN': if ob.pov.boolean_mod == "POV": - file.write("\tinside_vector <%.6g, %.6g, %.6g>\n" % - (ob.pov.inside_vector[0], - ob.pov.inside_vector[1], - ob.pov.inside_vector[2])) + file.write( + "\tinside_vector <%.6g, %.6g, %.6g>\n" + % ( + ob.pov.inside_vector[0], + ob.pov.inside_vector[1], + ob.pov.inside_vector[2], + ) + ) onceCSG = 1 if me.materials: @@ -3256,67 +4379,109 @@ def write_pov(filename, scene=None, info_callback=None): # POV object modifiers such as # hollow / sturm / double_illuminate etc. - write_object_modifiers(scene,ob,file) + write_object_modifiers(scene, ob, file) - #Importance for radiosity sampling added here: + # Importance for radiosity sampling added here: tabWrite("radiosity { \n") tabWrite("importance %3g \n" % importance) tabWrite("}\n") tabWrite("}\n") # End of mesh block - - ob_eval.to_mesh_clear() if csg: duplidata_ref = [] - _dupnames_seen = dict() # avoid duplicate output during introspection + _dupnames_seen = ( + dict() + ) # avoid duplicate output during introspection for ob in sel: - #matrix = global_matrix @ ob.matrix_world + # matrix = global_matrix @ ob.matrix_world if ob.is_instancer: - tabWrite("\n//--DupliObjects in %s--\n\n"% ob.name) - #ob.dupli_list_create(scene) #deprecated in 2.8 + tabWrite("\n//--DupliObjects in %s--\n\n" % ob.name) + # ob.dupli_list_create(scene) #deprecated in 2.8 depsgraph = bpy.context.evaluated_depsgraph_get() dup = "" if ob.is_modified(scene, 'RENDER'): - #modified object always unique so using object name rather than data name - dup = "#declare OB%s = union{\n" %(string_strip_hyphen(bpy.path.clean_name(ob.name))) + # modified object always unique so using object name rather than data name + dup = "#declare OB%s = union{\n" % ( + string_strip_hyphen(bpy.path.clean_name(ob.name)) + ) else: - dup = "#declare DATA%s = union{\n" %(string_strip_hyphen(bpy.path.clean_name(ob.name))) + dup = "#declare DATA%s = union{\n" % ( + string_strip_hyphen(bpy.path.clean_name(ob.name)) + ) for eachduplicate in depsgraph.object_instances: - if eachduplicate.is_instance: # Real dupli instance filtered because original included in list since 2.8 + if ( + eachduplicate.is_instance + ): # Real dupli instance filtered because original included in list since 2.8 _dupname = eachduplicate.object.name _dupobj = bpy.data.objects[_dupname] # BEGIN introspection for troubleshooting purposes if not "name" in dir(_dupobj.data): if _dupname not in _dupnames_seen: - print("WARNING: bpy.data.objects[%s].data (of type %s) has no 'name' attribute" % (_dupname, type(_dupobj.data))) + print( + "WARNING: bpy.data.objects[%s].data (of type %s) has no 'name' attribute" + % (_dupname, type(_dupobj.data)) + ) for _thing in dir(_dupobj): - print("|| %s.%s = %s" % (_dupname, _thing, getattr(_dupobj, _thing))) + print( + "|| %s.%s = %s" + % ( + _dupname, + _thing, + getattr(_dupobj, _thing), + ) + ) _dupnames_seen[_dupname] = 1 - print("''=> Unparseable objects so far: %s" % (_dupnames_seen)) + print( + "''=> Unparseable objects so far: %s" + % (_dupnames_seen) + ) else: _dupnames_seen[_dupname] += 1 continue # don't try to parse data objects with no name attribute # END introspection for troubleshooting purposes - duplidataname = "OB"+string_strip_hyphen(bpy.path.clean_name(_dupobj.data.name)) - dupmatrix = eachduplicate.matrix_world.copy() #has to be copied to not store instance since 2.8 - dup += ("\tobject {\n\t\tDATA%s\n\t\t%s\t}\n" %(string_strip_hyphen(bpy.path.clean_name(_dupobj.data.name)), MatrixAsPovString(ob.matrix_world.inverted() @ dupmatrix))) - #add object to a list so that it is not rendered for some instance_types - if ob.instance_type not in {'COLLECTION'} and duplidataname not in duplidata_ref: - duplidata_ref.append(duplidataname) #older key [string_strip_hyphen(bpy.path.clean_name("OB"+ob.name))] + duplidataname = "OB" + string_strip_hyphen( + bpy.path.clean_name(_dupobj.data.name) + ) + dupmatrix = ( + eachduplicate.matrix_world.copy() + ) # has to be copied to not store instance since 2.8 + dup += "\tobject {\n\t\tDATA%s\n\t\t%s\t}\n" % ( + string_strip_hyphen( + bpy.path.clean_name(_dupobj.data.name) + ), + MatrixAsPovString( + ob.matrix_world.inverted() @ dupmatrix + ), + ) + # add object to a list so that it is not rendered for some instance_types + if ( + ob.instance_type not in {'COLLECTION'} + and duplidataname not in duplidata_ref + ): + duplidata_ref.append( + duplidataname + ) # older key [string_strip_hyphen(bpy.path.clean_name("OB"+ob.name))] dup += "}\n" - #ob.dupli_list_clear()# just do not store any reference to instance since 2.8 + # ob.dupli_list_clear()# just do not store any reference to instance since 2.8 tabWrite(dup) else: continue - print("WARNING: Unparseable objects in current .blend file:\n''=> %s" % (_dupnames_seen)) + print( + "WARNING: Unparseable objects in current .blend file:\n''=> %s" + % (_dupnames_seen) + ) print("duplidata_ref = %s" % (duplidata_ref)) for data_name, inst in data_ref.items(): for ob_name, matrix_str in inst: - if ob_name not in duplidata_ref: #.items() for a dictionary - tabWrite("\n//----Blender Object Name:%s----\n" % ob_name) + if ( + ob_name not in duplidata_ref + ): # .items() for a dictionary + tabWrite( + "\n//----Blender Object Name:%s----\n" % ob_name + ) if ob.pov.object_as == '': tabWrite("object { \n") tabWrite("%s\n" % data_name) @@ -3332,16 +4497,22 @@ def write_pov(filename, scene=None, info_callback=None): operation = 'intersection' else: operation = mod.operation.lower() - mod_ob_name = string_strip_hyphen(bpy.path.clean_name(mod.object.name)) - mod_matrix = global_matrix @ mod.object.matrix_world - mod_ob_matrix = MatrixAsPovString(mod_matrix) - tabWrite("%s { \n"%operation) + mod_ob_name = string_strip_hyphen( + bpy.path.clean_name(mod.object.name) + ) + mod_matrix = ( + global_matrix @ mod.object.matrix_world + ) + mod_ob_matrix = MatrixAsPovString( + mod_matrix + ) + tabWrite("%s { \n" % operation) tabWrite("object { \n") tabWrite("%s\n" % data_name) tabWrite("%s\n" % matrix_str) tabWrite("}\n") tabWrite("object { \n") - tabWrite("%s\n" % ('DATA'+ mod_ob_name)) + tabWrite("%s\n" % ('DATA' + mod_ob_name)) tabWrite("%s\n" % mod_ob_matrix) tabWrite("}\n") tabWrite("}\n") @@ -3360,45 +4531,54 @@ def write_pov(filename, scene=None, info_callback=None): if not world: return #############Maurice#################################### - #These lines added to get sky gradient (visible with PNG output) + # These lines added to get sky gradient (visible with PNG output) if world: - #For simple flat background: + # For simple flat background: if not world.pov.use_sky_blend: # Non fully transparent background could premultiply alpha and avoid anti-aliasing # display issue: if render.alpha_mode == 'TRANSPARENT': - tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" % \ - (world.pov.horizon_color[:])) - #Currently using no alpha with Sky option: + tabWrite( + "background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" + % (world.pov.horizon_color[:]) + ) + # Currently using no alpha with Sky option: elif render.alpha_mode == 'SKY': - tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0>}\n" % (world.pov.horizon_color[:])) - #StraightAlpha: + tabWrite( + "background {rgbt<%.3g, %.3g, %.3g, 0>}\n" + % (world.pov.horizon_color[:]) + ) + # StraightAlpha: # XXX Does not exists anymore - #else: - #tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.pov.horizon_color[:])) + # else: + # tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.pov.horizon_color[:])) worldTexCount = 0 - #For Background image textures - for t in world.texture_slots: # risk to write several sky_spheres but maybe ok. + # For Background image textures + for ( + t + ) in ( + world.texture_slots + ): # risk to write several sky_spheres but maybe ok. if t and t.texture.type is not None: worldTexCount += 1 # XXX No enable checkbox for world textures yet (report it?) - #if t and t.texture.type == 'IMAGE' and t.use: + # if t and t.texture.type == 'IMAGE' and t.use: if t and t.texture.type == 'IMAGE': image_filename = path_image(t.texture.image) if t.texture.image.filepath != image_filename: t.texture.image.filepath = image_filename if image_filename != "" and t.use_map_blend: texturesBlend = image_filename - #colvalue = t.default_value + # colvalue = t.default_value t_blend = t # Commented below was an idea to make the Background image oriented as camera # taken here: -#http://news.pov.org/pov.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.pov.org%3E/ + # http://news.pov.org/pov.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.pov.org%3E/ # Replace 4/3 by the ratio of each image found by some custom or existing # function - #mappingBlend = (" translate <%.4g,%.4g,%.4g> rotate z*degrees" \ + # mappingBlend = (" translate <%.4g,%.4g,%.4g> rotate z*degrees" \ # "(atan((camLocation - camLookAt).x/(camLocation - " \ # "camLookAt).y)) rotate x*degrees(atan((camLocation - " \ # "camLookAt).y/(camLocation - camLookAt).z)) rotate y*" \ @@ -3407,7 +4587,7 @@ def write_pov(filename, scene=None, info_callback=None): # (t_blend.offset.x / 10 , t_blend.offset.y / 10 , # t_blend.offset.z / 10, t_blend.scale.x , # t_blend.scale.y , t_blend.scale.z)) - #using camera rotation valuesdirectly from blender seems much easier + # using camera rotation valuesdirectly from blender seems much easier if t_blend.texture_coords == 'ANGMAP': mappingBlend = "" else: @@ -3418,14 +4598,22 @@ def write_pov(filename, scene=None, info_callback=None): # Further Scale by 2 and translate by -1 are # required for the sky_sphere not to repeat - mappingBlend = "scale 2 scale <%.4g,%.4g,%.4g> translate -1 " \ - "translate <%.4g,%.4g,%.4g> rotate<0,0,0> " % \ - ((1.0 / t_blend.scale.x), - (1.0 / t_blend.scale.y), - (1.0 / t_blend.scale.z), - 0.5-(0.5/t_blend.scale.x)- t_blend.offset.x, - 0.5-(0.5/t_blend.scale.y)- t_blend.offset.y, - t_blend.offset.z) + mappingBlend = ( + "scale 2 scale <%.4g,%.4g,%.4g> translate -1 " + "translate <%.4g,%.4g,%.4g> rotate<0,0,0> " + % ( + (1.0 / t_blend.scale.x), + (1.0 / t_blend.scale.y), + (1.0 / t_blend.scale.z), + 0.5 + - (0.5 / t_blend.scale.x) + - t_blend.offset.x, + 0.5 + - (0.5 / t_blend.scale.y) + - t_blend.offset.y, + t_blend.offset.z, + ) + ) # The initial position and rotation of the pov camera is probably creating # the rotation offset should look into it someday but at least background @@ -3435,18 +4623,26 @@ def write_pov(filename, scene=None, info_callback=None): # size of the plane relative to camera. tabWrite("sky_sphere {\n") tabWrite("pigment {\n") - tabWrite("image_map{%s \"%s\" %s}\n" % \ - (imageFormat(texturesBlend), texturesBlend, imgMapBG(t_blend))) + tabWrite( + "image_map{%s \"%s\" %s}\n" + % ( + imageFormat(texturesBlend), + texturesBlend, + imgMapBG(t_blend), + ) + ) tabWrite("}\n") tabWrite("%s\n" % (mappingBlend)) # The following layered pigment opacifies to black over the texture for # transmit below 1 or otherwise adds to itself - tabWrite("pigment {rgb 0 transmit %s}\n" % (t.texture.intensity)) + tabWrite( + "pigment {rgb 0 transmit %s}\n" % (t.texture.intensity) + ) tabWrite("}\n") - #tabWrite("scale 2\n") - #tabWrite("translate -1\n") + # tabWrite("scale 2\n") + # tabWrite("translate -1\n") - #For only Background gradient + # For only Background gradient if worldTexCount == 0: if world.pov.use_sky_blend: @@ -3457,28 +4653,40 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("gradient y\n") tabWrite("color_map {\n") # XXX Does not exists anymore - #if render.alpha_mode == 'STRAIGHT': - #tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.pov.horizon_color[:])) - #tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.pov.zenith_color[:])) + # if render.alpha_mode == 'STRAIGHT': + # tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.pov.horizon_color[:])) + # tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.pov.zenith_color[:])) if render.alpha_mode == 'TRANSPARENT': - tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.pov.horizon_color[:])) + tabWrite( + "[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" + % (world.pov.horizon_color[:]) + ) # aa premult not solved with transmit 1 - tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.pov.zenith_color[:])) + tabWrite( + "[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" + % (world.pov.zenith_color[:]) + ) else: - tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.pov.horizon_color[:])) - tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.pov.zenith_color[:])) + tabWrite( + "[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" + % (world.pov.horizon_color[:]) + ) + tabWrite( + "[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" + % (world.pov.zenith_color[:]) + ) tabWrite("}\n") tabWrite("}\n") tabWrite("}\n") # Sky_sphere alpha (transmit) is not translating into image alpha the same # way as 'background' - #if world.pov.light_settings.use_indirect_light: + # if world.pov.light_settings.use_indirect_light: # scene.pov.radio_enable=1 # Maybe change the above to a function copyInternalRenderer settings when # user pushes a button, then: - #scene.pov.radio_enable = world.pov.light_settings.use_indirect_light + # scene.pov.radio_enable = world.pov.light_settings.use_indirect_light # and other such translations but maybe this would not be allowed either? ############################################################### @@ -3487,32 +4695,48 @@ def write_pov(filename, scene=None, info_callback=None): if mist.use_mist: tabWrite("fog {\n") - if mist.falloff=='LINEAR': - tabWrite("distance %.6f\n" % ((mist.start+mist.depth)*0.368)) - elif mist.falloff=='QUADRATIC': # n**2 or squrt(n)? - tabWrite("distance %.6f\n" % ((mist.start+mist.depth)**2*0.368)) - elif mist.falloff=='INVERSE_QUADRATIC': # n**2 or squrt(n)? - tabWrite("distance %.6f\n" % ((mist.start+mist.depth)**2*0.368)) - tabWrite("color rgbt<%.3g, %.3g, %.3g, %.3g>\n" % \ - (*world.pov.horizon_color, 1.0 - mist.intensity)) - #tabWrite("fog_offset %.6f\n" % mist.start) #create a pov property to prepend - #tabWrite("fog_alt %.6f\n" % mist.height) #XXX right? - #tabWrite("turbulence 0.2\n") - #tabWrite("turb_depth 0.3\n") - tabWrite("fog_type 1\n") #type2 for height + if mist.falloff == 'LINEAR': + tabWrite( + "distance %.6f\n" % ((mist.start + mist.depth) * 0.368) + ) + elif mist.falloff == 'QUADRATIC': # n**2 or squrt(n)? + tabWrite( + "distance %.6f\n" % ((mist.start + mist.depth) ** 2 * 0.368) + ) + elif mist.falloff == 'INVERSE_QUADRATIC': # n**2 or squrt(n)? + tabWrite( + "distance %.6f\n" % ((mist.start + mist.depth) ** 2 * 0.368) + ) + tabWrite( + "color rgbt<%.3g, %.3g, %.3g, %.3g>\n" + % (*world.pov.horizon_color, 1.0 - mist.intensity) + ) + # tabWrite("fog_offset %.6f\n" % mist.start) #create a pov property to prepend + # tabWrite("fog_alt %.6f\n" % mist.height) #XXX right? + # tabWrite("turbulence 0.2\n") + # tabWrite("turb_depth 0.3\n") + tabWrite("fog_type 1\n") # type2 for height tabWrite("}\n") if scene.pov.media_enable: tabWrite("media {\n") - tabWrite("scattering { %d, rgb %.12f*<%.4g, %.4g, %.4g>\n" % \ - (int(scene.pov.media_scattering_type), - (scene.pov.media_diffusion_scale), - *(scene.pov.media_diffusion_color[:]))) + tabWrite( + "scattering { %d, rgb %.12f*<%.4g, %.4g, %.4g>\n" + % ( + int(scene.pov.media_scattering_type), + (scene.pov.media_diffusion_scale), + *(scene.pov.media_diffusion_color[:]), + ) + ) if scene.pov.media_scattering_type == '5': tabWrite("eccentricity %.3g\n" % scene.pov.media_eccentricity) tabWrite("}\n") - tabWrite("absorption %.12f*<%.4g, %.4g, %.4g>\n" % \ - (scene.pov.media_absorption_scale, - *(scene.pov.media_absorption_color[:]))) + tabWrite( + "absorption %.12f*<%.4g, %.4g, %.4g>\n" + % ( + scene.pov.media_absorption_scale, + *(scene.pov.media_absorption_color[:]), + ) + ) tabWrite("\n") tabWrite("samples %.d\n" % scene.pov.media_samples) tabWrite("}\n") @@ -3524,15 +4748,23 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("max_trace_level %d\n" % scene.pov.max_trace_level) if scene.pov.charset != 'ascii': - file.write(" charset %s\n"%scene.pov.charset) + file.write(" charset %s\n" % scene.pov.charset) if scene.pov.global_settings_advanced: if scene.pov.radio_enable == False: - file.write(" adc_bailout %.6f\n"%scene.pov.adc_bailout) - file.write(" ambient_light <%.6f,%.6f,%.6f>\n"%scene.pov.ambient_light[:]) - file.write(" irid_wavelength <%.6f,%.6f,%.6f>\n"%scene.pov.irid_wavelength[:]) - file.write(" max_intersections %s\n"%scene.pov.max_intersections) - file.write(" number_of_waves %s\n"%scene.pov.number_of_waves) - file.write(" noise_generator %s\n"%scene.pov.noise_generator) + file.write(" adc_bailout %.6f\n" % scene.pov.adc_bailout) + file.write( + " ambient_light <%.6f,%.6f,%.6f>\n" + % scene.pov.ambient_light[:] + ) + file.write( + " irid_wavelength <%.6f,%.6f,%.6f>\n" + % scene.pov.irid_wavelength[:] + ) + file.write( + " max_intersections %s\n" % scene.pov.max_intersections + ) + file.write(" number_of_waves %s\n" % scene.pov.number_of_waves) + file.write(" noise_generator %s\n" % scene.pov.noise_generator) if scene.pov.radio_enable: tabWrite("radiosity {\n") tabWrite("adc_bailout %.4g\n" % scene.pov.radio_adc_bailout) @@ -3540,7 +4772,9 @@ def write_pov(filename, scene=None, info_callback=None): tabWrite("count %d\n" % scene.pov.radio_count) tabWrite("error_bound %.4g\n" % scene.pov.radio_error_bound) tabWrite("gray_threshold %.4g\n" % scene.pov.radio_gray_threshold) - tabWrite("low_error_factor %.4g\n" % scene.pov.radio_low_error_factor) + tabWrite( + "low_error_factor %.4g\n" % scene.pov.radio_low_error_factor + ) tabWrite("maximum_reuse %.4g\n" % scene.pov.radio_maximum_reuse) tabWrite("minimum_reuse %.4g\n" % scene.pov.radio_minimum_reuse) tabWrite("nearest_count %d\n" % scene.pov.radio_nearest_count) @@ -3559,47 +4793,70 @@ def write_pov(filename, scene=None, info_callback=None): if material.pov_subsurface_scattering.use and onceSss: # In pov, the scale has reversed influence compared to blender. these number # should correct that - tabWrite("mm_per_unit %.6f\n" % \ - (material.pov_subsurface_scattering.scale * 1000.0)) - # 1000 rather than scale * (-100.0) + 15.0)) + tabWrite( + "mm_per_unit %.6f\n" + % (material.pov_subsurface_scattering.scale * 1000.0) + ) + # 1000 rather than scale * (-100.0) + 15.0)) # In POV-Ray, the scale factor for all subsurface shaders needs to be the same # formerly sslt_samples were multiplied by 100 instead of 10 - sslt_samples = (11 - material.pov_subsurface_scattering.error_threshold) * 10 - - tabWrite("subsurface { samples %d, %d }\n" % (sslt_samples, sslt_samples / 10)) + sslt_samples = ( + 11 - material.pov_subsurface_scattering.error_threshold + ) * 10 + + tabWrite( + "subsurface { samples %d, %d }\n" + % (sslt_samples, sslt_samples / 10) + ) onceSss = 0 if world and onceAmbient: - tabWrite("ambient_light rgb<%.3g, %.3g, %.3g>\n" % world.pov.ambient_color[:]) + tabWrite( + "ambient_light rgb<%.3g, %.3g, %.3g>\n" + % world.pov.ambient_color[:] + ) onceAmbient = 0 if scene.pov.photon_enable: - if (oncePhotons and - (material.pov.refraction_type == "2" or - material.pov.photons_reflection == True)): + if oncePhotons and ( + material.pov.refraction_type == "2" + or material.pov.photons_reflection == True + ): tabWrite("photons {\n") tabWrite("spacing %.6f\n" % scene.pov.photon_spacing) - tabWrite("max_trace_level %d\n" % scene.pov.photon_max_trace_level) - tabWrite("adc_bailout %.3g\n" % scene.pov.photon_adc_bailout) - tabWrite("gather %d, %d\n" % (scene.pov.photon_gather_min, - scene.pov.photon_gather_max)) + tabWrite( + "max_trace_level %d\n" + % scene.pov.photon_max_trace_level + ) + tabWrite( + "adc_bailout %.3g\n" % scene.pov.photon_adc_bailout + ) + tabWrite( + "gather %d, %d\n" + % ( + scene.pov.photon_gather_min, + scene.pov.photon_gather_max, + ) + ) if scene.pov.photon_map_file_save_load in {'save'}: filePhName = 'Photon_map_file.ph' if scene.pov.photon_map_file != '': - filePhName = scene.pov.photon_map_file+'.ph' + filePhName = scene.pov.photon_map_file + '.ph' filePhDir = tempfile.gettempdir() path = bpy.path.abspath(scene.pov.photon_map_dir) if os.path.exists(path): filePhDir = path - fullFileName = os.path.join(filePhDir,filePhName) - tabWrite('save_file "%s"\n'%fullFileName) + fullFileName = os.path.join(filePhDir, filePhName) + tabWrite('save_file "%s"\n' % fullFileName) scene.pov.photon_map_file = fullFileName if scene.pov.photon_map_file_save_load in {'load'}: - fullFileName = bpy.path.abspath(scene.pov.photon_map_file) + fullFileName = bpy.path.abspath( + scene.pov.photon_map_file + ) if os.path.exists(fullFileName): - tabWrite('load_file "%s"\n'%fullFileName) + tabWrite('load_file "%s"\n' % fullFileName) tabWrite("}\n") oncePhotons = 0 @@ -3608,9 +4865,13 @@ def write_pov(filename, scene=None, info_callback=None): 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: - file.write("//#include \"/home/user/directory/animation_include_file.inc\"\n") + file.write( + "#declare CURFRAMENUM = %d;\n" % bpy.context.scene.frame_current + ) + # Change path and uncomment to add an animated include file by hand: + file.write( + "//#include \"/home/user/directory/animation_include_file.inc\"\n" + ) for txt in bpy.data.texts: if txt.pov.custom_code == 'both': # Why are the newlines needed? @@ -3618,20 +4879,23 @@ def write_pov(filename, scene=None, info_callback=None): file.write(txt.as_string()) file.write("\n") - #sel = renderable_objects(scene) #removed for booleans + # sel = renderable_objects(scene) #removed for booleans if comments: - file.write("//----------------------------------------------\n" \ - "//--Exported with POV-Ray exporter for Blender--\n" \ - "//----------------------------------------------\n\n") + file.write( + "//----------------------------------------------\n" + "//--Exported with POV-Ray exporter for Blender--\n" + "//----------------------------------------------\n\n" + ) file.write("#version 3.7;\n") - file.write("#declare Default_texture = texture{pigment {rgb 0.8} " - "finish {brilliance 3.8} }\n\n") + file.write( + "#declare Default_texture = texture{pigment {rgb 0.8} " + "finish {brilliance 3.8} }\n\n" + ) if comments: file.write("\n//--Global settings--\n\n") exportGlobalSettings(scene) - if comments: file.write("\n//--Custom Code--\n\n") exportCustomCode() @@ -3639,13 +4903,21 @@ def write_pov(filename, scene=None, info_callback=None): if comments: file.write("\n//--Patterns Definitions--\n\n") LocalPatternNames = [] - for texture in bpy.data.textures: #ok? + 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 of the above + currentPatName = string_strip_hyphen( + bpy.path.clean_name(texture.name) + ) + # string_strip_hyphen(patternNames[texture.name]) #maybe instead of the above LocalPatternNames.append(currentPatName) - #use above list to prevent writing texture instances several times and assign in mats? - if (texture.type not in {'NONE', 'IMAGE'} and texture.pov.tex_pattern_type == 'emulator')or(texture.type in {'NONE', 'IMAGE'} and texture.pov.tex_pattern_type != 'emulator'): + # use above list to prevent writing texture instances several times and assign in mats? + if ( + texture.type not in {'NONE', 'IMAGE'} + and texture.pov.tex_pattern_type == 'emulator' + ) or ( + texture.type in {'NONE', 'IMAGE'} + and texture.pov.tex_pattern_type != 'emulator' + ): file.write("\n#declare PAT_%s = \n" % currentPatName) file.write(shading.exportPattern(texture, string_strip_hyphen)) file.write("\n") @@ -3676,50 +4948,91 @@ def write_pov(filename, scene=None, info_callback=None): csg = True sel = renderable_objects(scene) - exportLamps([L for L in sel if (L.type == 'LIGHT' and L.pov.object_as != 'RAINBOW')]) + exportLamps( + [L for L in sel if (L.type == 'LIGHT' and L.pov.object_as != 'RAINBOW')] + ) if comments: file.write("\n//--Rainbows--\n\n") - exportRainbows([L for L in sel if (L.type == 'LIGHT' and L.pov.object_as == 'RAINBOW')]) - + exportRainbows( + [L for L in sel if (L.type == 'LIGHT' and L.pov.object_as == 'RAINBOW')] + ) if comments: file.write("\n//--Special Curves--\n\n") for c in sel: if c.is_modified(scene, 'RENDER'): - continue #don't export as pov curves objects with modifiers, but as mesh - elif c.type == 'CURVE' and (c.pov.curveshape in {'lathe','sphere_sweep','loft','birail'}): - exportCurves(scene,c) - + continue # don't export as pov curves objects with modifiers, but as mesh + elif c.type == 'CURVE' and ( + c.pov.curveshape in {'lathe', 'sphere_sweep', 'loft', 'birail'} + ): + exportCurves(scene, c) 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 srgb 0.8 }}\n") # Convert all materials to strings we can access directly per vertex. - #exportMaterials() - shading.writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, None) # default material + # exportMaterials() + shading.writeMaterial( + using_uberpov, + DEF_MAT_NAME, + scene, + tabWrite, + safety, + comments, + uniqueName, + materialNames, + None, + ) # default material for material in bpy.data.materials: if material.users > 0: if material.pov.material_use_nodes: ntree = material.node_tree - povMatName=string_strip_hyphen(bpy.path.clean_name(material.name)) - if len(ntree.nodes)==0: - file.write('#declare %s = texture {%s}\n'%(povMatName,color)) + povMatName = string_strip_hyphen( + bpy.path.clean_name(material.name) + ) + if len(ntree.nodes) == 0: + file.write( + '#declare %s = texture {%s}\n' % (povMatName, color) + ) else: - shading.write_nodes(scene,povMatName,ntree,file) + shading.write_nodes(scene, povMatName, ntree, file) for node in ntree.nodes: if node: if node.bl_idname == "PovrayOutputNode": if node.inputs["Texture"].is_linked: for link in ntree.links: - if link.to_node.bl_idname == "PovrayOutputNode": - povMatName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName + if ( + link.to_node.bl_idname + == "PovrayOutputNode" + ): + povMatName = ( + string_strip_hyphen( + bpy.path.clean_name( + link.from_node.name + ) + ) + + "_%s" % povMatName + ) else: - file.write('#declare %s = texture {%s}\n'%(povMatName,color)) + file.write( + '#declare %s = texture {%s}\n' + % (povMatName, color) + ) else: - shading.writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, material) + shading.writeMaterial( + using_uberpov, + DEF_MAT_NAME, + scene, + tabWrite, + safety, + comments, + uniqueName, + materialNames, + material, + ) # attributes are all the variables needed by the other python file... if comments: file.write("\n") @@ -3731,24 +5044,28 @@ def write_pov(filename, scene=None, info_callback=None): exportMeshes(scene, sel, csg) - #What follow used to happen here: - #exportCamera() - #exportWorld(scene.world) - #exportGlobalSettings(scene) + # What follow used to happen here: + # exportCamera() + # exportWorld(scene.world) + # exportGlobalSettings(scene) # MR:..and the order was important for implementing pov 3.7 baking # (mesh camera) comment for the record # CR: Baking should be a special case than. If "baking", than we could change the order. - #print("pov file closed %s" % file.closed) + # print("pov file closed %s" % file.closed) file.close() - #print("pov file closed %s" % file.closed) + # print("pov file closed %s" % file.closed) -def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_image): +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] + feature_set = bpy.context.preferences.addons[ + __package__ + ].preferences.branch_feature_set_povray + using_uberpov = feature_set == 'uberpov' + # scene = bpy.data.scenes[0] scene = bpy.context.scene render = scene.render @@ -3757,12 +5074,11 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag file = open(filename_ini, "w") file.write("Version=3.7\n") - #write povray text stream to temporary file of same name with _log suffix - #file.write("All_File='%s'\n" % filename_log) + # write povray text stream to temporary file of same name with _log suffix + # file.write("All_File='%s'\n" % filename_log) # DEBUG.OUT log if none specified: file.write("All_File=1\n") - file.write("Input_File_Name='%s'\n" % filename_pov) file.write("Output_File_Name='%s'\n" % filename_image) @@ -3777,7 +5093,9 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag file.write("Start_Row=%4g\n" % (1.0 - render.border_max_y)) file.write("End_Row=%4g\n" % (1.0 - render.border_min_y)) - file.write("Bounding_Method=2\n") # The new automatic BSP is faster in most scenes + file.write( + "Bounding_Method=2\n" + ) # The new automatic BSP is faster in most scenes # Activated (turn this back off when better live exchange is done between the two programs # (see next comment) @@ -3786,7 +5104,7 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag # PNG, with POV-Ray 3.7, can show background color with alpha. In the long run using the # POV-Ray interactive preview like bishop 3D could solve the preview for all formats. file.write("Output_File_Type=N\n") - #file.write("Output_File_Type=T\n") # TGA, best progressive loading + # file.write("Output_File_Type=T\n") # TGA, best progressive loading file.write("Output_Alpha=1\n") if scene.pov.antialias_enable: @@ -3801,10 +5119,16 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag file.write("Antialias_Depth=%d\n" % scene.pov.antialias_depth) file.write("Antialias_Threshold=%.3g\n" % scene.pov.antialias_threshold) if using_uberpov and scene.pov.antialias_method == '2': - file.write("Sampling_Method=%s\n" % method[scene.pov.antialias_method]) - file.write("Antialias_Confidence=%.3g\n" % scene.pov.antialias_confidence) + file.write( + "Sampling_Method=%s\n" % method[scene.pov.antialias_method] + ) + file.write( + "Antialias_Confidence=%.3g\n" % scene.pov.antialias_confidence + ) else: - file.write("Sampling_Method=%s\n" % method[scene.pov.antialias_method]) + file.write( + "Sampling_Method=%s\n" % method[scene.pov.antialias_method] + ) file.write("Antialias_Gamma=%.3g\n" % scene.pov.antialias_gamma) if scene.pov.jitter_enable: file.write("Jitter=on\n") @@ -3814,13 +5138,14 @@ def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_imag else: file.write("Antialias=off\n") - #print("ini file closed %s" % file.closed) + # print("ini file closed %s" % file.closed) file.close() - #print("ini file closed %s" % file.closed) + # print("ini file closed %s" % file.closed) class PovrayRender(bpy.types.RenderEngine): """Define the external renderer""" + bl_idname = 'POVRAY_RENDER' bl_label = "Persitence Of Vision" bl_use_shading_nodes_custom = False @@ -3837,14 +5162,19 @@ class PovrayRender(bpy.types.RenderEngine): if os.path.exists(pov_binary): return pov_binary else: - print("User Preferences path to povray %r NOT FOUND, checking $PATH" % pov_binary) + print( + "User Preferences path to povray %r NOT FOUND, checking $PATH" + % pov_binary + ) # Windows Only # assume if there is a 64bit binary that the user has a 64bit capable OS if sys.platform[:3] == "win": import winreg - win_reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, - "Software\\POV-Ray\\v3.7\\Windows") + + win_reg_key = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, "Software\\POV-Ray\\v3.7\\Windows" + ) win_home = winreg.QueryValueEx(win_reg_key, "Home")[0] # First try 64bits UberPOV @@ -3881,21 +5211,30 @@ class PovrayRender(bpy.types.RenderEngine): 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: - self._temp_file_in = tempfile.NamedTemporaryFile(suffix=".pov", delete=False).name + self._temp_file_in = tempfile.NamedTemporaryFile( + suffix=".pov", delete=False + ).name # PNG with POV 3.7, can show the background color with alpha. In the long run using the # POV-Ray interactive preview like bishop 3D could solve the preview for all formats. - self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name - #self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name - self._temp_file_ini = tempfile.NamedTemporaryFile(suffix=".ini", delete=False).name - self._temp_file_log = os.path.join(tempfile.gettempdir(), "alltext.out") + self._temp_file_out = tempfile.NamedTemporaryFile( + suffix=".png", delete=False + ).name + # self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name + self._temp_file_ini = tempfile.NamedTemporaryFile( + suffix=".ini", delete=False + ).name + self._temp_file_log = os.path.join( + tempfile.gettempdir(), "alltext.out" + ) else: self._temp_file_in = povPath + ".pov" # PNG with POV 3.7, can show the background color with alpha. In the long run using the # POV-Ray interactive preview like bishop 3D could solve the preview for all formats. self._temp_file_out = renderImagePath + ".png" - #self._temp_file_out = renderImagePath + ".tga" + # self._temp_file_out = renderImagePath + ".tga" self._temp_file_ini = povPath + ".ini" logPath = bpy.path.abspath(scene.pov.scene_path).replace('\\', '/') self._temp_file_log = os.path.join(logPath, "alltext.out") @@ -3907,7 +5246,8 @@ class PovrayRender(bpy.types.RenderEngine): #self._temp_file_out = "/test.tga" self._temp_file_ini = "/test.ini" ''' - if scene.pov.text_block == "": + if scene.pov.text_block == "": + def info_callback(txt): self.update_stats("", "POV-Ray 3.7: " + txt) @@ -3917,6 +5257,7 @@ class PovrayRender(bpy.types.RenderEngine): write_pov(self._temp_file_in, scene, info_callback) else: pass + def _render(self, depsgraph): """Export necessary files and render image.""" scene = bpy.context.scene @@ -3927,12 +5268,20 @@ class PovrayRender(bpy.types.RenderEngine): pov_binary = PovrayRender._locate_binary() if not pov_binary: - print("POV-Ray 3.7: could not execute povray, possibly POV-Ray isn't installed") + print( + "POV-Ray 3.7: could not execute povray, possibly POV-Ray isn't installed" + ) return False - write_pov_ini(scene, self._temp_file_ini, self._temp_file_log, self._temp_file_in, self._temp_file_out) + write_pov_ini( + scene, + self._temp_file_ini, + self._temp_file_log, + self._temp_file_in, + self._temp_file_out, + ) - print ("***-STARTING-***") + print("***-STARTING-***") extra_args = [] @@ -3943,7 +5292,7 @@ class PovrayRender(bpy.types.RenderEngine): self._is_windows = False if sys.platform[:3] == "win": self._is_windows = True - if"/EXIT" not in extra_args and not scene.pov.pov_editor: + 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 @@ -3951,14 +5300,18 @@ class PovrayRender(bpy.types.RenderEngine): # Start Rendering! try: - self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self._process = subprocess.Popen( + [pov_binary, self._temp_file_ini] + extra_args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) except OSError: # TODO, report api print("POV-Ray 3.7: could not execute '%s'" % pov_binary) import traceback + traceback.print_exc() - print ("***-DONE-***") + print("***-DONE-***") return False else: @@ -3988,9 +5341,11 @@ 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) + def render(self, depsgraph): """Export necessary files from text editor and render image.""" import tempfile + scene = bpy.context.scene r = scene.render x = int(r.resolution_x * r.resolution_percentage * 0.01) @@ -4022,22 +5377,32 @@ class PovrayRender(bpy.types.RenderEngine): return True - if bpy.context.scene.pov.text_block !="": + if bpy.context.scene.pov.text_block != "": if scene.pov.tempfiles_enable: - self._temp_file_in = tempfile.NamedTemporaryFile(suffix=".pov", delete=False).name - self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name - #self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name - self._temp_file_ini = tempfile.NamedTemporaryFile(suffix=".ini", delete=False).name - self._temp_file_log = os.path.join(tempfile.gettempdir(), "alltext.out") + self._temp_file_in = tempfile.NamedTemporaryFile( + suffix=".pov", delete=False + ).name + self._temp_file_out = tempfile.NamedTemporaryFile( + suffix=".png", delete=False + ).name + # self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name + self._temp_file_ini = tempfile.NamedTemporaryFile( + suffix=".ini", delete=False + ).name + self._temp_file_log = os.path.join( + tempfile.gettempdir(), "alltext.out" + ) else: povPath = scene.pov.text_block renderImagePath = os.path.splitext(povPath)[0] - self._temp_file_out =os.path.join(preview_dir, renderImagePath ) + self._temp_file_out = os.path.join(preview_dir, renderImagePath) self._temp_file_in = os.path.join(preview_dir, povPath) - self._temp_file_ini = os.path.join(preview_dir, (os.path.splitext(self._temp_file_in)[0]+".INI")) + self._temp_file_ini = os.path.join( + preview_dir, + (os.path.splitext(self._temp_file_in)[0] + ".INI"), + ) self._temp_file_log = os.path.join(preview_dir, "alltext.out") - ''' try: os.remove(self._temp_file_in) # so as not to load the old file @@ -4046,7 +5411,7 @@ class PovrayRender(bpy.types.RenderEngine): ''' print(scene.pov.text_block) text = bpy.data.texts[scene.pov.text_block] - file=open("%s"%self._temp_file_in,"w") + file = open("%s" % self._temp_file_in, "w") # Why are the newlines needed? file.write("\n") file.write(text.as_string()) @@ -4059,16 +5424,25 @@ class PovrayRender(bpy.types.RenderEngine): pov_binary = PovrayRender._locate_binary() if not pov_binary: - print("POV-Ray 3.7: could not execute povray, possibly POV-Ray isn't installed") + print( + "POV-Ray 3.7: could not execute povray, possibly POV-Ray isn't installed" + ) return False - # start ini UI options export - self.update_stats("", "POV-Ray 3.7: Exporting ini options from Blender") + self.update_stats( + "", "POV-Ray 3.7: Exporting ini options from Blender" + ) - write_pov_ini(scene, self._temp_file_ini, self._temp_file_log, self._temp_file_in, self._temp_file_out) + write_pov_ini( + scene, + self._temp_file_ini, + self._temp_file_log, + self._temp_file_in, + self._temp_file_out, + ) - print ("***-STARTING-***") + print("***-STARTING-***") extra_args = [] @@ -4077,7 +5451,7 @@ class PovrayRender(bpy.types.RenderEngine): extra_args.append(newArg) if sys.platform[:3] == "win": - if"/EXIT" not in extra_args and not scene.pov.pov_editor: + 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 @@ -4085,31 +5459,38 @@ class PovrayRender(bpy.types.RenderEngine): # Start Rendering! try: - if sys.platform[:3] != "win" and scene.pov.sdl_window_enable: #segfault on linux == False !!! + if ( + sys.platform[:3] != "win" and scene.pov.sdl_window_enable + ): # segfault on linux == False !!! env = {'POV_DISPLAY_SCALED': 'off'} env.update(os.environ) - self._process = subprocess.Popen([pov_binary, self._temp_file_ini], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - env=env) + self._process = subprocess.Popen( + [pov_binary, self._temp_file_ini], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=env, + ) else: - self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + self._process = subprocess.Popen( + [pov_binary, self._temp_file_ini] + extra_args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) except OSError: # TODO, report api print("POV-Ray 3.7: could not execute '%s'" % pov_binary) import traceback + traceback.print_exc() - print ("***-DONE-***") + print("***-DONE-***") return False else: print("Engine ready!...") print("Command line arguments passed: " + str(extra_args)) - #return True + # return True self.update_stats("", "POV-Ray 3.7: Parsing File") - - # Indented in main function now so repeated here but still not working # to bring back render result to its buffer @@ -4127,8 +5508,10 @@ class PovrayRender(bpy.types.RenderEngine): except RuntimeError: print("***POV ERROR WHILE READING OUTPUT FILE***") self.end_result(result) - #print(self._temp_file_log) #bring the pov log to blender console with proper path? - with open(self._temp_file_log) as f: # The with keyword automatically closes the file when you are done + # print(self._temp_file_log) #bring the pov log to blender console with proper path? + with open( + self._temp_file_log + ) as f: # The with keyword automatically closes the file when you are done print(f.read()) self.update_stats("", "") @@ -4137,16 +5520,18 @@ class PovrayRender(bpy.types.RenderEngine): self._cleanup() else: - ##WIP output format - ## if r.image_settings.file_format == 'OPENEXR': - ## fformat = 'EXR' - ## render.image_settings.color_mode = 'RGBA' - ## else: - ## fformat = 'TGA' - ## r.image_settings.file_format = 'TARGA' - ## r.image_settings.color_mode = 'RGBA' - - blendSceneName = bpy.data.filepath.split(os.path.sep)[-1].split(".")[0] + ##WIP output format + ## if r.image_settings.file_format == 'OPENEXR': + ## fformat = 'EXR' + ## render.image_settings.color_mode = 'RGBA' + ## else: + ## fformat = 'TGA' + ## r.image_settings.file_format = 'TARGA' + ## r.image_settings.color_mode = 'RGBA' + + blendSceneName = bpy.data.filepath.split(os.path.sep)[-1].split( + "." + )[0] povSceneName = "" povPath = "" renderImagePath = "" @@ -4157,7 +5542,9 @@ class PovrayRender(bpy.types.RenderEngine): if not scene.pov.tempfiles_enable: # check paths - povPath = bpy.path.abspath(scene.pov.scene_path).replace('\\', '/') + povPath = bpy.path.abspath(scene.pov.scene_path).replace( + '\\', '/' + ) if povPath == "": if bpy.data.is_saved: povPath = bpy.path.abspath("//") @@ -4174,13 +5561,20 @@ class PovrayRender(bpy.types.RenderEngine): os.makedirs(povPath) except: import traceback + traceback.print_exc() - print("POV-Ray 3.7: Cannot create scenes directory: %r" % povPath) - self.update_stats("", "POV-Ray 3.7: Cannot create scenes directory %r" % \ - povPath) + print( + "POV-Ray 3.7: Cannot create scenes directory: %r" + % povPath + ) + self.update_stats( + "", + "POV-Ray 3.7: Cannot create scenes directory %r" + % povPath, + ) time.sleep(2.0) - #return + # return ''' # Bug in POV-Ray RC3 @@ -4218,7 +5612,7 @@ class PovrayRender(bpy.types.RenderEngine): print("POV-Ray 3.7: Invalid scene name") self.update_stats("", "POV-Ray 3.7: Invalid scene name") time.sleep(2.0) - #return + # return povSceneName = os.path.splitext(povSceneName)[0] print("Scene name: " + povSceneName) @@ -4231,8 +5625,8 @@ class PovrayRender(bpy.types.RenderEngine): renderImagePath = povPath # Bugfix for POV-Ray RC3 bug # renderImagePath = os.path.realpath(renderImagePath) # Bugfix for POV-Ray RC3 bug - #print("Export path: %s" % povPath) - #print("Render Image path: %s" % renderImagePath) + # print("Export path: %s" % povPath) + # print("Render Image path: %s" % renderImagePath) # start export self.update_stats("", "POV-Ray 3.7: Exporting data from Blender") @@ -4241,13 +5635,12 @@ class PovrayRender(bpy.types.RenderEngine): if not self._render(depsgraph): self.update_stats("", "POV-Ray 3.7: Not found") - #return + # return - #r = scene.render + # r = scene.render # compute resolution - #x = int(r.resolution_x * r.resolution_percentage * 0.01) - #y = int(r.resolution_y * r.resolution_percentage * 0.01) - + # x = int(r.resolution_x * r.resolution_percentage * 0.01) + # y = int(r.resolution_y * r.resolution_percentage * 0.01) # Wait for the file to be created # XXX This is no more valid, as 3.7 always creates output file once render is finished! @@ -4272,7 +5665,11 @@ class PovrayRender(bpy.types.RenderEngine): # XXX This is working for UNIX, not sure whether it might need adjustments for # other OSs # First replace is for windows - t_data = str(t_data).replace('\\r\\n', '\\n').replace('\\r', '\r') + t_data = ( + str(t_data) + .replace('\\r\\n', '\\n') + .replace('\\r', '\r') + ) lines = t_data.split('\\n') last_line += lines[0] lines[0] = last_line @@ -4283,7 +5680,11 @@ class PovrayRender(bpy.types.RenderEngine): _pov_rendering = True match = percent.findall(str(data)) if match: - self.update_stats("", "POV-Ray 3.7: Rendering File (%s%%)" % match[-1]) + self.update_stats( + "", + "POV-Ray 3.7: Rendering File (%s%%)" + % match[-1], + ) else: self.update_stats("", "POV-Ray 3.7: Rendering File") @@ -4292,7 +5693,7 @@ class PovrayRender(bpy.types.RenderEngine): if os.path.exists(self._temp_file_out): # print("***POV FILE OK***") - #self.update_stats("", "POV-Ray 3.7: Rendering") + # self.update_stats("", "POV-Ray 3.7: Rendering") # prev_size = -1 @@ -4304,8 +5705,8 @@ class PovrayRender(bpy.types.RenderEngine): # print("***POV UPDATING IMAGE***") result = self.begin_result(0, 0, x, y) # XXX, tests for border render. - #result = self.begin_result(xmin, ymin, xmax - xmin, ymax - ymin) - #result = self.begin_result(0, 0, xmax - xmin, ymax - ymin) + # result = self.begin_result(xmin, ymin, xmax - xmin, ymax - ymin) + # result = self.begin_result(0, 0, xmax - xmin, ymax - ymin) lay = result.layers[0] # This assumes the file has been fully written We wait a bit, just in case! @@ -4313,7 +5714,7 @@ class PovrayRender(bpy.types.RenderEngine): try: lay.load_from_file(self._temp_file_out) # XXX, tests for border render. - #lay.load_from_file(self._temp_file_out, xmin, ymin) + # lay.load_from_file(self._temp_file_out, xmin, ymin) except RuntimeError: print("***POV ERROR WHILE READING OUTPUT FILE***") @@ -4370,8 +5771,10 @@ class PovrayRender(bpy.types.RenderEngine): print("***POV FILE FINISHED***") - #print(filename_log) #bring the pov log to blender console with proper path? - with open(self._temp_file_log) as f: # The with keyword automatically closes the file when you are done + # print(filename_log) #bring the pov log to blender console with proper path? + with open( + self._temp_file_log + ) as f: # The with keyword automatically closes the file when you are done print(f.read()) self.update_stats("", "") @@ -4385,24 +5788,30 @@ class PovrayRender(bpy.types.RenderEngine): ################################################################################## 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): - tex=bpy.context.object.active_material.active_texture #context.texture - texPrevName=string_strip_hyphen(bpy.path.clean_name(tex.name))+"_prev" + tex = ( + bpy.context.object.active_material.active_texture + ) # context.texture + texPrevName = ( + string_strip_hyphen(bpy.path.clean_name(tex.name)) + "_prev" + ) ## Make sure Preview directory exists and is empty if not os.path.isdir(preview_dir): os.mkdir(preview_dir) - iniPrevFile=os.path.join(preview_dir, "Preview.ini") - inputPrevFile=os.path.join(preview_dir, "Preview.pov") - outputPrevFile=os.path.join(preview_dir, texPrevName) + iniPrevFile = os.path.join(preview_dir, "Preview.ini") + inputPrevFile = os.path.join(preview_dir, "Preview.pov") + outputPrevFile = os.path.join(preview_dir, texPrevName) ##################### ini ########################################## - fileIni=open("%s"%iniPrevFile,"w") + 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('Input_File_Name="%s"\n' % inputPrevFile) + fileIni.write('Output_File_Name="%s.png"\n' % outputPrevFile) fileIni.write('Library_Path="%s"\n' % preview_dir) fileIni.write('Width=256\n') fileIni.write('Height=256\n') @@ -4415,16 +5824,20 @@ class RenderPovTexturePreview(Operator): 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 = open("%s" % inputPrevFile, "w") + PATname = "PAT_" + string_strip_hyphen(bpy.path.clean_name(tex.name)) + filePov.write("#declare %s = \n" % PATname) filePov.write(shading.exportPattern(tex, string_strip_hyphen)) 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( + " 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") @@ -4448,11 +5861,17 @@ class RenderPovTexturePreview(Operator): 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) + 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 = subprocess.Popen( + ["%s" % pov_binary, "-d", "%s" % iniPrevFile], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) p1.wait() tex.use_nodes = True @@ -4461,23 +5880,25 @@ class RenderPovTexturePreview(Operator): for n in tree.nodes: tree.nodes.remove(n) im = tree.nodes.new("TextureNodeImage") - pathPrev="%s.png"%outputPrevFile + pathPrev = "%s.png" % outputPrevFile im.image = bpy.data.images.load(pathPrev) - name=pathPrev - name=name.split("/") - name=name[len(name)-1] + name = pathPrev + name = name.split("/") + name = name[len(name) - 1] im.name = name - im.location = 200,200 + 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" + previewer.location = 400, 400 + links.new(im.outputs[0], previewer.inputs[0]) + # tex.type="IMAGE" # makes clip extend possible + # tex.extension="CLIP" 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" @@ -4487,22 +5908,18 @@ class RunPovTextRender(Operator): scene = context.scene scene.pov.text_block = context.space_data.text.name - bpy.ops.render.render() - #empty text name property engain + # empty text name property engain scene.pov.text_block = "" return {'FINISHED'} -classes = ( - PovrayRender, - RenderPovTexturePreview, - RunPovTextRender, -) + +classes = (PovrayRender, RenderPovTexturePreview, RunPovTextRender) def register(): - #from bpy.utils import register_class + # from bpy.utils import register_class for cls in classes: register_class(cls) diff --git a/render_povray/shading.py b/render_povray/shading.py index 0789824538f7f7dfe484b3bb1d50567e13193ef3..825cdd700df77afd5e43ddd5df63cd17b994fd1a 100644 --- a/render_povray/shading.py +++ b/render_povray/shading.py @@ -1,3 +1,23 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# #**** END GPL LICENSE BLOCK #**** + +# <pep8 compliant> + """Translate complex shaders to exported POV textures.""" import bpy diff --git a/render_povray/ui.py b/render_povray/ui.py index 33d2daa42ad9ef1fbd09c2d5ef77ce6dd6556c2d..b21943754d6572ec6318e7fbf4db421905a507e9 100644 --- a/render_povray/ui.py +++ b/render_povray/ui.py @@ -18,25 +18,28 @@ # <pep8 compliant> """User interface for the POV tools""" + import bpy -import sys #really import here and in render.py? -import os #really import here and in render.py? +import sys # really import here and in render.py? +import os # really import here and in render.py? from os.path import isfile from bl_operators.presets import AddPresetBase from bpy.utils import register_class, unregister_class from bpy.types import ( - Operator, - UIList, - Panel, - # Brush, - Material, - Light, - World, - ParticleSettings, - FreestyleLineStyle - ) + Operator, + UIList, + Panel, + Brush, + Material, + Light, + World, + ParticleSettings, + FreestyleLineStyle, +) + # Example of wrapping every class 'as is' from bl_ui import properties_output + for member in dir(properties_output): subclass = getattr(properties_output, member) try: @@ -46,6 +49,7 @@ for member in dir(properties_output): del properties_output from bl_ui import properties_view_layer + for member in dir(properties_view_layer): subclass = getattr(properties_view_layer, member) try: @@ -56,20 +60,22 @@ del properties_view_layer # Use some of the existing buttons. from bl_ui import properties_render -#DEPRECATED#properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') -#DEPRECATED#properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') + +# DEPRECATED#properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') +# DEPRECATED#properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') # properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') -#TORECREATE##DEPRECATED#properties_render.RENDER_PT_shading.COMPAT_ENGINES.add('POVRAY_RENDER') -#DEPRECATED#properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') +# TORECREATE##DEPRECATED#properties_render.RENDER_PT_shading.COMPAT_ENGINES.add('POVRAY_RENDER') +# DEPRECATED#properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') del properties_render # Use only a subset of the world panels from bl_ui import properties_world -#TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') + +# TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER') -#TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') -#TORECREATE##DEPRECATED#properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') +# TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') +# TORECREATE##DEPRECATED#properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') del properties_world @@ -77,6 +83,7 @@ del properties_world from bl_ui import properties_texture from bl_ui.properties_texture import context_tex_datablock from bl_ui.properties_texture import texture_filter_common + for member in dir(properties_texture): subclass = getattr(properties_texture, member) try: @@ -87,6 +94,7 @@ del properties_texture # Physics Main wrapping every class 'as is' from bl_ui import properties_physics_common + for member in dir(properties_physics_common): subclass = getattr(properties_physics_common, member) try: @@ -97,6 +105,7 @@ del properties_physics_common # Physics Rigid Bodies wrapping every class 'as is' from bl_ui import properties_physics_rigidbody + for member in dir(properties_physics_rigidbody): subclass = getattr(properties_physics_rigidbody, member) try: @@ -107,6 +116,7 @@ del properties_physics_rigidbody # Physics Rigid Body Constraint wrapping every class 'as is' from bl_ui import properties_physics_rigidbody_constraint + for member in dir(properties_physics_rigidbody_constraint): subclass = getattr(properties_physics_rigidbody_constraint, member) try: @@ -117,6 +127,7 @@ del properties_physics_rigidbody_constraint # Physics Smoke wrapping every class 'as is' from bl_ui import properties_physics_smoke + for member in dir(properties_physics_smoke): subclass = getattr(properties_physics_smoke, member) try: @@ -127,6 +138,7 @@ del properties_physics_smoke # Physics softbody wrapping every class 'as is' from bl_ui import properties_physics_softbody + for member in dir(properties_physics_softbody): subclass = getattr(properties_physics_softbody, member) try: @@ -137,6 +149,7 @@ del properties_physics_softbody # Physics Fluid wrapping every class 'as is' from bl_ui import properties_physics_fluid + for member in dir(properties_physics_fluid): subclass = getattr(properties_physics_fluid, member) try: @@ -147,6 +160,7 @@ del properties_physics_fluid # Physics Field wrapping every class 'as is' from bl_ui import properties_physics_field + for member in dir(properties_physics_field): subclass = getattr(properties_physics_field, member) try: @@ -157,6 +171,7 @@ del properties_physics_field # Physics Cloth wrapping every class 'as is' from bl_ui import properties_physics_cloth + for member in dir(properties_physics_cloth): subclass = getattr(properties_physics_cloth, member) try: @@ -167,6 +182,7 @@ del properties_physics_cloth # Physics Dynamic Paint wrapping every class 'as is' from bl_ui import properties_physics_dynamicpaint + for member in dir(properties_physics_dynamicpaint): subclass = getattr(properties_physics_dynamicpaint, member) try: @@ -178,6 +194,7 @@ del properties_physics_dynamicpaint # Example of wrapping every class 'as is' from bl_ui import properties_data_modifier + for member in dir(properties_data_modifier): subclass = getattr(properties_data_modifier, member) try: @@ -188,20 +205,22 @@ del properties_data_modifier # Example of wrapping every class 'as is' except some from bl_ui import properties_material + for member in dir(properties_material): subclass = getattr(properties_material, member) try: # mat=bpy.context.active_object.active_material # if (mat and mat.pov.type == "SURFACE" - # and not (mat.pov.material_use_nodes or mat.use_nodes)): + # and not (mat.pov.material_use_nodes or mat.use_nodes)): # and (engine in cls.COMPAT_ENGINES)) if subclasses were sorted - subclass.COMPAT_ENGINES.add('POVRAY_RENDER') + subclass.COMPAT_ENGINES.add('POVRAY_RENDER') except: pass del properties_material from bl_ui import properties_data_camera + for member in dir(properties_data_camera): subclass = getattr(properties_data_camera, member) try: @@ -211,10 +230,11 @@ for member in dir(properties_data_camera): del properties_data_camera - - from bl_ui import properties_particle as properties_particle -for member in dir(properties_particle): # add all "particle" panels from blender + +for member in dir( + properties_particle +): # add all "particle" panels from blender subclass = getattr(properties_particle, member) try: subclass.COMPAT_ENGINES.add('POVRAY_RENDER') @@ -224,6 +244,7 @@ del properties_particle # Example of wrapping every class 'as is' from bl_ui import properties_output + for member in dir(properties_output): subclass = getattr(properties_output, member) try: @@ -232,6 +253,7 @@ for member in dir(properties_output): pass del properties_output + class WORLD_MT_POV_presets(bpy.types.Menu): bl_label = "World Presets" preset_subdir = "pov/world" @@ -241,14 +263,13 @@ class WORLD_MT_POV_presets(bpy.types.Menu): class WORLD_OT_POV_add_preset(AddPresetBase, Operator): '''Add a World Preset''' + bl_idname = "object.world_preset_add" bl_label = "Add World Preset" preset_menu = "WORLD_MT_POV_presets" # variable used for all preset values - preset_defines = [ - "scene = bpy.context.scene" - ] + preset_defines = ["scene = bpy.context.scene"] # properties to store in the preset preset_values = [ @@ -268,26 +289,31 @@ class WORLD_OT_POV_add_preset(AddPresetBase, Operator): "scene.pov.media_absorption_scale", "scene.pov.media_absorption_color", "scene.pov.media_eccentricity", - ] + ] # where to store the preset preset_subdir = "pov/world" + def check_material(mat): if mat is not None: if mat.use_nodes: - if not mat.node_tree: #FORMERLY : #mat.active_node_material is not None: + if ( + not mat.node_tree + ): # FORMERLY : #mat.active_node_material is not None: return True return False return True return False + def simple_material(mat): """Test if a material uses nodes""" if (mat is not None) and (not mat.use_nodes): return True return False + def check_add_mesh_extra_objects(): """Test if Add mesh extra objects addon is activated @@ -298,6 +324,7 @@ def check_add_mesh_extra_objects(): return True return False + def locate_docpath(): """POV can be installed with some include files. @@ -311,20 +338,25 @@ def locate_docpath(): if os.path.exists(pov_documents): return pov_documents else: - print("User Preferences path to povray documents %r NOT FOUND, checking $PATH" % pov_documents) + print( + "User Preferences path to povray documents %r NOT FOUND, checking $PATH" + % pov_documents + ) # Windows Only if sys.platform[:3] == "win": import winreg + try: - win_reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, - "Software\\POV-Ray\\v3.7\\Windows") + win_reg_key = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, "Software\\POV-Ray\\v3.7\\Windows" + ) win_docpath = winreg.QueryValueEx(win_reg_key, "DocPath")[0] pov_documents = os.path.join(win_docpath, "Insert Menu") if os.path.exists(pov_documents): return pov_documents except FileNotFoundError: - return"" + return "" # search the path all os's pov_documents_default = "include" @@ -336,6 +368,7 @@ def locate_docpath(): return pov_documents return "" + def pov_context_tex_datablock(context): """Texture context type recreated as deprecated in blender 2.8""" @@ -344,7 +377,9 @@ def pov_context_tex_datablock(context): return idblock # idblock = bpy.context.active_object.active_material - idblock = bpy.context.scene.view_layers["View Layer"].objects.active.active_material + idblock = bpy.context.scene.view_layers[ + "View Layer" + ].objects.active.active_material if idblock: return idblock @@ -365,7 +400,8 @@ def pov_context_tex_datablock(context): if idblock: return idblock -class RenderButtonsPanel(): + +class RenderButtonsPanel: """Use this class to define buttons from the render tab of properties window.""" @@ -377,11 +413,13 @@ class RenderButtonsPanel(): @classmethod def poll(cls, context): rd = context.scene.render - return (rd.engine in cls.COMPAT_ENGINES) + return rd.engine in cls.COMPAT_ENGINES -class ModifierButtonsPanel(): + +class ModifierButtonsPanel: """Use this class to define buttons from the modifier tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "modifier" @@ -393,9 +431,11 @@ class ModifierButtonsPanel(): rd = context.scene.render return mods and (rd.engine in cls.COMPAT_ENGINES) -class MaterialButtonsPanel(): + +class MaterialButtonsPanel: """Use this class to define buttons from the material tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "material" @@ -408,9 +448,10 @@ class MaterialButtonsPanel(): return mat and (rd.engine in cls.COMPAT_ENGINES) -class TextureButtonsPanel(): +class TextureButtonsPanel: """Use this class to define buttons from the texture tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "texture" @@ -422,18 +463,20 @@ class TextureButtonsPanel(): rd = context.scene.render return tex 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)) +# @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(): +class ObjectButtonsPanel: """Use this class to define buttons from the object tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "object" @@ -445,9 +488,11 @@ class ObjectButtonsPanel(): rd = context.scene.render return obj and (rd.engine in cls.COMPAT_ENGINES) -class CameraDataButtonsPanel(): + +class CameraDataButtonsPanel: """Use this class to define buttons from the camera data tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "data" @@ -459,9 +504,11 @@ class CameraDataButtonsPanel(): rd = context.scene.render return cam and (rd.engine in cls.COMPAT_ENGINES) -class WorldButtonsPanel(): + +class WorldButtonsPanel: """Use this class to define buttons from the world tab of properties window.""" + bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "world" @@ -473,9 +520,11 @@ class WorldButtonsPanel(): rd = context.scene.render return wld and (rd.engine in cls.COMPAT_ENGINES) -class TextButtonsPanel(): + +class TextButtonsPanel: """Use this class to define buttons from the side tab of text window.""" + bl_space_type = 'TEXT_EDITOR' bl_region_type = 'UI' bl_label = "POV-Ray" @@ -487,29 +536,50 @@ class TextButtonsPanel(): rd = context.scene.render return text and (rd.engine in cls.COMPAT_ENGINES) + from bl_ui import properties_data_mesh + # These panels are kept -properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add('POVRAY_RENDER') +properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add( + 'POVRAY_RENDER' +) properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add('POVRAY_RENDER') ## make some native panels contextual to some object variable ## by recreating custom panels inheriting their properties + class PovDataButtonsPanel(properties_data_mesh.MeshButtonsPanel): """Use this class to define buttons from the edit data tab of properties window.""" + COMPAT_ENGINES = {'POVRAY_RENDER'} - POV_OBJECT_TYPES = {'PLANE', 'BOX', 'SPHERE', 'CYLINDER', 'CONE', 'TORUS', 'BLOB', - 'ISOSURFACE', 'SUPERELLIPSOID', 'SUPERTORUS', 'HEIGHT_FIELD', - 'PARAMETRIC', 'POLYCIRCLE'} + POV_OBJECT_TYPES = { + 'PLANE', + 'BOX', + 'SPHERE', + 'CYLINDER', + 'CONE', + 'TORUS', + 'BLOB', + 'ISOSURFACE', + 'SUPERELLIPSOID', + 'SUPERTORUS', + 'HEIGHT_FIELD', + 'PARAMETRIC', + 'POLYCIRCLE', + } @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object # We use our parent class poll func too, avoids to re-define too much things... - return (super(PovDataButtonsPanel, cls).poll(context) and - obj and obj.pov.object_as not in cls.POV_OBJECT_TYPES) + return ( + super(PovDataButtonsPanel, cls).poll(context) + and obj + and obj.pov.object_as not in cls.POV_OBJECT_TYPES + ) # We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups). @@ -558,25 +628,26 @@ class DATA_PT_POV_customdata(PovDataButtonsPanel, Panel): draw = properties_data_mesh.DATA_PT_customdata.draw - del properties_data_mesh ################################################################################ # from bl_ui import properties_data_light # for member in dir(properties_data_light): - # subclass = getattr(properties_data_light, member) - # try: - # subclass.COMPAT_ENGINES.add('POVRAY_RENDER') - # except: - # pass +# subclass = getattr(properties_data_light, member) +# try: +# subclass.COMPAT_ENGINES.add('POVRAY_RENDER') +# except: +# pass # del properties_data_light #########################LIGHTS################################ from bl_ui import properties_data_light # These panels are kept -properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('POVRAY_RENDER') +properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add( + 'POVRAY_RENDER' +) properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER') ## make some native panels contextual to some object variable @@ -584,6 +655,7 @@ properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER') class PovLampButtonsPanel(properties_data_light.DataButtonsPanel): """Use this class to define buttons from the light data tab of properties window.""" + COMPAT_ENGINES = {'POVRAY_RENDER'} POV_OBJECT_TYPES = {'RAINBOW'} @@ -592,29 +664,35 @@ class PovLampButtonsPanel(properties_data_light.DataButtonsPanel): engine = context.scene.render.engine obj = context.object # We use our parent class poll func too, avoids to re-define too much things... - return (super(PovLampButtonsPanel, cls).poll(context) and - obj and obj.pov.object_as not in cls.POV_OBJECT_TYPES) + return ( + super(PovLampButtonsPanel, cls).poll(context) + and obj + and obj.pov.object_as not in cls.POV_OBJECT_TYPES + ) # We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups). # Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work. # So we simply have to explicitly copy here the interesting bits. ;) + class LIGHT_PT_POV_preview(PovLampButtonsPanel, Panel): bl_label = properties_data_light.DATA_PT_preview.bl_label draw = properties_data_light.DATA_PT_preview.draw + class LIGHT_PT_POV_light(PovLampButtonsPanel, Panel): bl_label = properties_data_light.DATA_PT_light.bl_label draw = properties_data_light.DATA_PT_light.draw + class LIGHT_MT_POV_presets(bpy.types.Menu): """Use this class to define preset menu for pov lights.""" bl_label = "Lamp Presets" - preset_subdir = "pov/lamp" + preset_subdir = "pov/light" preset_operator = "script.execute_preset" draw = bpy.types.Menu.draw_preset @@ -622,29 +700,21 @@ class LIGHT_MT_POV_presets(bpy.types.Menu): class LIGHT_OT_POV_add_preset(AddPresetBase, Operator): """Use this class to define pov world buttons.""" - '''Add a Lamp Preset''' + '''Add a Light Preset''' bl_idname = "object.light_preset_add" - bl_label = "Add Lamp Preset" + bl_label = "Add Light Preset" preset_menu = "LIGHT_MT_POV_presets" # variable used for all preset values - preset_defines = [ - "lightdata = bpy.context.object.data" - ] + preset_defines = ["lightdata = bpy.context.object.data"] # properties to store in the preset - preset_values = [ - "lightdata.type", - "lightdata.color", - ] + preset_values = ["lightdata.type", "lightdata.color"] # where to store the preset preset_subdir = "pov/light" - - - # Draw into the existing light panel def light_panel_func(self, context): layout = self.layout @@ -652,7 +722,10 @@ def light_panel_func(self, context): row = layout.row(align=True) row.menu(LIGHT_MT_POV_presets.__name__, text=LIGHT_MT_POV_presets.bl_label) row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon='ADD') - row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon='REMOVE').remove_active = True + row.operator( + LIGHT_OT_POV_add_preset.bl_idname, text="", icon='REMOVE' + ).remove_active = True + '''#TORECREATE##DEPRECATED# class LIGHT_PT_POV_sunsky(PovLampButtonsPanel, Panel): @@ -667,8 +740,10 @@ class LIGHT_PT_POV_sunsky(PovLampButtonsPanel, Panel): draw = properties_data_light.DATA_PT_sunsky.draw ''' + + class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel): - bl_label = "Shadow" + bl_label = "Shadow" COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod @@ -695,7 +770,10 @@ class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel): col = split.column() - col.active = (lamp.shadow_method != 'BUFFER_SHADOW' or lamp.shadow_buffer_type != 'DEEP') + col.active = ( + lamp.shadow_method != 'BUFFER_SHADOW' + or lamp.shadow_buffer_type != 'DEEP' + ) col.prop(lamp, "use_halo") sub = col.column(align=True) sub.active = lamp.use_halo @@ -747,6 +825,7 @@ class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel): sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") + ''' if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': split = layout.split() @@ -846,6 +925,7 @@ class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel): sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End") ''' + class LIGHT_PT_POV_area(PovLampButtonsPanel, Panel): bl_label = properties_data_light.DATA_PT_area.bl_label @@ -857,6 +937,7 @@ class LIGHT_PT_POV_area(PovLampButtonsPanel, Panel): draw = properties_data_light.DATA_PT_area.draw + class LIGHT_PT_POV_spot(PovLampButtonsPanel, Panel): bl_label = properties_data_light.DATA_PT_spot.bl_label @@ -865,8 +946,10 @@ class LIGHT_PT_POV_spot(PovLampButtonsPanel, Panel): lamp = context.light engine = context.scene.render.engine return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) + draw = properties_data_light.DATA_PT_spot.draw + class LIGHT_PT_POV_falloff_curve(PovLampButtonsPanel, Panel): bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options @@ -876,20 +959,32 @@ class LIGHT_PT_POV_falloff_curve(PovLampButtonsPanel, Panel): lamp = context.light engine = context.scene.render.engine - return (lamp and lamp.type in {'POINT', 'SPOT'} and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES) + return ( + lamp + and lamp.type in {'POINT', 'SPOT'} + and lamp.falloff_type == 'CUSTOM_CURVE' + ) and (engine in cls.COMPAT_ENGINES) + draw = properties_data_light.DATA_PT_falloff_curve.draw + class OBJECT_PT_POV_rainbow(PovLampButtonsPanel, Panel): """Use this class to define buttons from the rainbow panel of properties window. inheriting lamp buttons panel class""" + bl_label = "POV-Ray Rainbow" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'RAINBOW' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'RAINBOW' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -899,33 +994,58 @@ class OBJECT_PT_POV_rainbow(PovLampButtonsPanel, Panel): if obj.pov.object_as == 'RAINBOW': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') - col.label(text="Rainbow projection angle: " + str(obj.data.spot_size)) + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) + col.label( + text="Rainbow projection angle: " + str(obj.data.spot_size) + ) col.label(text="Rainbow width: " + str(obj.data.spot_blend)) - col.label(text="Rainbow distance: " + str(obj.data.shadow_buffer_clip_start)) + col.label( + text="Rainbow distance: " + + str(obj.data.shadow_buffer_clip_start) + ) col.label(text="Rainbow arc angle: " + str(obj.pov.arc_angle)) - col.label(text="Rainbow falloff angle: " + str(obj.pov.falloff_angle)) + col.label( + text="Rainbow falloff angle: " + str(obj.pov.falloff_angle) + ) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.cone_update", text="Update", icon="MESH_CONE" + ) - layout.operator("pov.cone_update", text="Update",icon="MESH_CONE") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.data, "spot_size", text="Rainbow Projection Angle") col.prop(obj.data, "spot_blend", text="Rainbow width") - col.prop(obj.data, "shadow_buffer_clip_start", text="Visibility distance") + col.prop( + obj.data, + "shadow_buffer_clip_start", + text="Visibility distance", + ) col.prop(obj.pov, "arc_angle") col.prop(obj.pov, "falloff_angle") + del properties_data_light ############################################################################### + class WORLD_PT_POV_world(WorldButtonsPanel, Panel): """Use this class to define pov world buttons.""" + bl_label = "World" COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -935,9 +1055,13 @@ class WORLD_PT_POV_world(WorldButtonsPanel, Panel): world = context.world.pov row = layout.row(align=True) - row.menu(WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label) + row.menu( + WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label + ) row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon='ADD') - row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon='REMOVE').remove_active = True + row.operator( + WORLD_OT_POV_add_preset.bl_idname, text="", icon='REMOVE' + ).remove_active = True row = layout.row() row.prop(world, "use_sky_paper") @@ -951,9 +1075,10 @@ class WORLD_PT_POV_world(WorldButtonsPanel, Panel): col.active = world.use_sky_blend row.column().prop(world, "ambient_color") - #row = layout.row() - #row.prop(world, "exposure") #Re-implement later as a light multiplier - #row.prop(world, "color_range") + # row = layout.row() + # row.prop(world, "exposure") #Re-implement later as a light multiplier + # row.prop(world, "color_range") + class WORLD_PT_POV_mist(WorldButtonsPanel, Panel): """Use this class to define pov mist buttons.""" @@ -986,6 +1111,7 @@ class WORLD_PT_POV_mist(WorldButtonsPanel, Panel): layout.prop(world.mist_settings, "falloff") + class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel): """Use this class to define pov ini settingss buttons.""" @@ -993,20 +1119,23 @@ class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'POVRAY_RENDER'} - def draw_header(self, context): scene = context.scene if scene.pov.tempfiles_enable: - self.layout.prop(scene.pov, "tempfiles_enable", text="", icon='AUTO') + self.layout.prop( + scene.pov, "tempfiles_enable", text="", icon='AUTO' + ) else: - self.layout.prop(scene.pov, "tempfiles_enable", text="", icon='CONSOLE') + self.layout.prop( + scene.pov, "tempfiles_enable", text="", icon='CONSOLE' + ) def draw(self, context): layout = self.layout scene = context.scene - layout.active = (scene.pov.max_trace_level != 0) + layout.active = scene.pov.max_trace_level != 0 split = layout.split() col = split.column() @@ -1015,15 +1144,15 @@ class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel): split = layout.split() layout.active = not scene.pov.tempfiles_enable - #if not scene.pov.tempfiles_enable: + # if not scene.pov.tempfiles_enable: split.prop(scene.pov, "deletefiles_enable", text="Delete files") split.prop(scene.pov, "pov_editor", text="POV Editor") col = layout.column() col.prop(scene.pov, "scene_name", text="Name") col.prop(scene.pov, "scene_path", text="Path to files") - #col.prop(scene.pov, "scene_path", text="Path to POV-file") - #col.prop(scene.pov, "renderimage_path", text="Path to image") + # col.prop(scene.pov, "scene_path", text="Path to POV-file") + # col.prop(scene.pov, "renderimage_path", text="Path to image") split = layout.split() split.prop(scene.pov, "indentation_character", text="Indent") @@ -1046,46 +1175,57 @@ class RENDER_PT_POV_render_settings(RenderButtonsPanel, Panel): def draw_header(self, context): scene = context.scene if scene.pov.global_settings_advanced: - self.layout.prop(scene.pov, "global_settings_advanced", text="", icon='SETTINGS') + self.layout.prop( + scene.pov, "global_settings_advanced", text="", icon='SETTINGS' + ) else: - self.layout.prop(scene.pov, "global_settings_advanced", text="", icon='PREFERENCES') + self.layout.prop( + scene.pov, + "global_settings_advanced", + text="", + icon='PREFERENCES', + ) + def draw(self, context): layout = self.layout scene = context.scene rd = context.scene.render - #layout.active = (scene.pov.max_trace_level != 0) + # layout.active = (scene.pov.max_trace_level != 0) if sys.platform[:3] != "win": - layout.prop(scene.pov, "sdl_window_enable", text="POV-Ray SDL Window") + layout.prop( + scene.pov, "sdl_window_enable", text="POV-Ray SDL Window" + ) col = layout.column() col.label(text="Main Path Tracing:") col.prop(scene.pov, "max_trace_level", text="Ray Depth") align = True layout.active = scene.pov.global_settings_advanced - layout.prop(scene.pov,"charset") - row = layout.row(align = align) - row.prop(scene.pov,"adc_bailout") - row = layout.row(align = align) - row.prop(scene.pov,"ambient_light") - row = layout.row(align = align) - row.prop(scene.pov,"irid_wavelength") - row = layout.row(align = align) - row.prop(scene.pov,"max_intersections") - row = layout.row(align = align) - row.prop(scene.pov,"number_of_waves") - row = layout.row(align = align) - row.prop(scene.pov,"noise_generator") + layout.prop(scene.pov, "charset") + row = layout.row(align=align) + row.prop(scene.pov, "adc_bailout") + row = layout.row(align=align) + row.prop(scene.pov, "ambient_light") + row = layout.row(align=align) + row.prop(scene.pov, "irid_wavelength") + row = layout.row(align=align) + row.prop(scene.pov, "max_intersections") + row = layout.row(align=align) + row.prop(scene.pov, "number_of_waves") + row = layout.row(align=align) + row.prop(scene.pov, "noise_generator") split = layout.split() split.label(text="Shading:") split = layout.split() - row = split.row(align = align) + row = split.row(align=align) row.prop(scene.pov, "use_shadows") row.prop(scene.pov, "alpha_mode") + class RENDER_PT_POV_photons(RenderButtonsPanel, Panel): """Use this class to define pov photons buttons.""" @@ -1094,20 +1234,25 @@ class RENDER_PT_POV_photons(RenderButtonsPanel, Panel): COMPAT_ENGINES = {'POVRAY_RENDER'} # def draw_header(self, context): - # self.layout.label(icon='SETTINGS') + # self.layout.label(icon='SETTINGS') def draw_header(self, context): scene = context.scene if scene.pov.photon_enable: - self.layout.prop(scene.pov, "photon_enable", text="", icon='PMARKER_ACT') + self.layout.prop( + scene.pov, "photon_enable", text="", icon='PMARKER_ACT' + ) else: - self.layout.prop(scene.pov, "photon_enable", text="", icon='PMARKER') + self.layout.prop( + scene.pov, "photon_enable", text="", icon='PMARKER' + ) + def draw(self, context): scene = context.scene layout = self.layout layout.active = scene.pov.photon_enable col = layout.column() - #col.label(text="Global Photons:") + # col.label(text="Global Photons:") col.prop(scene.pov, "photon_max_trace_level", text="Photon Depth") split = layout.split() @@ -1120,17 +1265,17 @@ class RENDER_PT_POV_photons(RenderButtonsPanel, Panel): col.prop(scene.pov, "photon_adc_bailout", text="Photon ADC") col.prop(scene.pov, "photon_gather_max") - box = layout.box() box.label(text='Photon Map File:') row = box.row() - row.prop(scene.pov, "photon_map_file_save_load",expand = True) + row.prop(scene.pov, "photon_map_file_save_load", expand=True) if scene.pov.photon_map_file_save_load in {'save'}: box.prop(scene.pov, "photon_map_dir") box.prop(scene.pov, "photon_map_filename") if scene.pov.photon_map_file_save_load in {'load'}: box.prop(scene.pov, "photon_map_file") - #end main photons + # end main photons + class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel): """Use this class to define pov antialiasing buttons.""" @@ -1139,16 +1284,24 @@ class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'POVRAY_RENDER'} - def draw_header(self, context): prefs = bpy.context.preferences.addons[__package__].preferences scene = context.scene - if prefs.branch_feature_set_povray != 'uberpov' and scene.pov.antialias_method == '2': - self.layout.prop(scene.pov, "antialias_enable", text="", icon='ERROR') + if ( + prefs.branch_feature_set_povray != 'uberpov' + and scene.pov.antialias_method == '2' + ): + self.layout.prop( + scene.pov, "antialias_enable", text="", icon='ERROR' + ) elif scene.pov.antialias_enable: - self.layout.prop(scene.pov, "antialias_enable", text="", icon='ANTIALIASED') + self.layout.prop( + scene.pov, "antialias_enable", text="", icon='ANTIALIASED' + ) else: - self.layout.prop(scene.pov, "antialias_enable", text="", icon='ALIASED') + self.layout.prop( + scene.pov, "antialias_enable", text="", icon='ALIASED' + ) def draw(self, context): prefs = bpy.context.preferences.addons[__package__].preferences @@ -1160,7 +1313,10 @@ class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel): row = layout.row() row.prop(scene.pov, "antialias_method", text="") - if prefs.branch_feature_set_povray != 'uberpov' and scene.pov.antialias_method == '2': + if ( + prefs.branch_feature_set_povray != 'uberpov' + and scene.pov.antialias_method == '2' + ): col = layout.column() col.alignment = 'CENTER' col.label(text="Stochastic Anti Aliasing is") @@ -1186,26 +1342,35 @@ class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel): if prefs.branch_feature_set_povray == 'uberpov': row = layout.row() - row.prop(scene.pov, "antialias_confidence", text="AA Confidence") + row.prop( + scene.pov, "antialias_confidence", text="AA Confidence" + ) if scene.pov.antialias_method == '2': row.enabled = True else: row.enabled = False - class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel): """Use this class to define pov radiosity buttons.""" bl_label = "Diffuse Radiosity" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'POVRAY_RENDER'} + def draw_header(self, context): scene = context.scene if scene.pov.radio_enable: - self.layout.prop(scene.pov, "radio_enable", text="", icon='OUTLINER_OB_LIGHTPROBE') + self.layout.prop( + scene.pov, + "radio_enable", + text="", + icon='OUTLINER_OB_LIGHTPROBE', + ) else: - self.layout.prop(scene.pov, "radio_enable", text="", icon='LIGHTPROBE_CUBEMAP') + self.layout.prop( + scene.pov, "radio_enable", text="", icon='LIGHTPROBE_CUBEMAP' + ) def draw(self, context): layout = self.layout @@ -1248,9 +1413,6 @@ class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel): col.prop(scene.pov, "radio_subsurface") - - - class POV_RADIOSITY_MT_presets(bpy.types.Menu): """Use this class to define pov radiosity presets menu.""" @@ -1269,9 +1431,7 @@ class RENDER_OT_POV_radiosity_add_preset(AddPresetBase, Operator): preset_menu = "POV_RADIOSITY_MT_presets" # variable used for all preset values - preset_defines = [ - "scene = bpy.context.scene" - ] + preset_defines = ["scene = bpy.context.scene"] # properties to store in the preset preset_values = [ @@ -1292,23 +1452,28 @@ class RENDER_OT_POV_radiosity_add_preset(AddPresetBase, Operator): "scene.pov.radio_recursion_limit", "scene.pov.radio_pretrace_start", "scene.pov.radio_pretrace_end", - ] + ] # where to store the preset preset_subdir = "pov/radiosity" - - - # Draw into an existing panel def rad_panel_func(self, context): layout = self.layout row = layout.row(align=True) - row.menu(POV_RADIOSITY_MT_presets.__name__, text=POV_RADIOSITY_MT_presets.bl_label) - row.operator(RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='ADD') - row.operator(RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='REMOVE').remove_active = True + row.menu( + POV_RADIOSITY_MT_presets.__name__, + text=POV_RADIOSITY_MT_presets.bl_label, + ) + row.operator( + RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='ADD' + ) + row.operator( + RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='REMOVE' + ).remove_active = True + class RENDER_PT_POV_media(WorldButtonsPanel, Panel): """Use this class to define a pov global atmospheric media buttons.""" @@ -1344,6 +1509,8 @@ class RENDER_PT_POV_media(WorldButtonsPanel, Panel): if scene.pov.media_scattering_type == '5': col = layout.column() col.prop(scene.pov, "media_eccentricity", text="Eccentricity") + + ##class RENDER_PT_povray_baking(RenderButtonsPanel, Panel): ## bl_label = "Baking" ## COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -1361,15 +1528,16 @@ class RENDER_PT_POV_media(WorldButtonsPanel, Panel): ## ## layout.active = scene.pov.baking_enable + class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel): """Use this class to define pov modifier buttons. (For booleans)""" bl_label = "POV-Ray" COMPAT_ENGINES = {'POVRAY_RENDER'} - #def draw_header(self, context): - #scene = context.scene - #self.layout.prop(scene.pov, "boolean_mod", text="") + # def draw_header(self, context): + # scene = context.scene + # self.layout.prop(scene.pov, "boolean_mod", text="") def draw(self, context): scene = context.scene @@ -1381,7 +1549,7 @@ class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel): onceCSG = 0 for mod in ob.modifiers: if onceCSG == 0: - if mod : + if mod: if mod.type == 'BOOLEAN': col.prop(ob.pov, "boolean_mod") onceCSG = 1 @@ -1392,6 +1560,7 @@ class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel): # Inside Vector for CSG col.prop(ob.pov, "inside_vector") + class MATERIAL_MT_POV_sss_presets(bpy.types.Menu): """Use this class to define pov sss preset menu.""" @@ -1400,22 +1569,22 @@ class MATERIAL_MT_POV_sss_presets(bpy.types.Menu): preset_operator = "script.execute_preset" draw = bpy.types.Menu.draw_preset + class MATERIAL_OT_POV_sss_add_preset(AddPresetBase, Operator): """Add an SSS Preset""" + bl_idname = "material.sss_preset_add" bl_label = "Add SSS Preset" preset_menu = "MATERIAL_MT_POV_sss_presets" # variable used for all preset values - preset_defines = [ - "material = bpy.context.material" - ] + preset_defines = ["material = bpy.context.material"] # properties to store in the preset preset_values = [ "material.pov_subsurface_scattering.radius", "material.pov_subsurface_scattering.color", - ] + ] # where to store the preset preset_subdir = "pov/material/sss" @@ -1432,28 +1601,39 @@ class MATERIAL_PT_POV_sss(MaterialButtonsPanel, Panel): def poll(cls, context): mat = context.material engine = context.scene.render.engine - return check_material(mat) and (mat.pov.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) + return ( + check_material(mat) + and (mat.pov.type in {'SURFACE', 'WIRE'}) + and (engine in cls.COMPAT_ENGINES) + ) def draw_header(self, context): - mat = context.material #FORMERLY : #active_node_mat(context.material) + mat = context.material # FORMERLY : #active_node_mat(context.material) sss = mat.pov_subsurface_scattering - self.layout.active = (not mat.pov.use_shadeless) + self.layout.active = not mat.pov.use_shadeless self.layout.prop(sss, "use", text="") def draw(self, context): layout = self.layout - mat = context.material #FORMERLY : #active_node_mat(context.material) + mat = context.material # FORMERLY : #active_node_mat(context.material) sss = mat.pov_subsurface_scattering layout.active = (sss.use) and (not mat.pov.use_shadeless) row = layout.row().split() sub = row.row(align=True).split(align=True, factor=0.75) - sub.menu(MATERIAL_MT_POV_sss_presets.__name__, text=MATERIAL_MT_POV_sss_presets.bl_label) - sub.operator(MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='ADD') - sub.operator(MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='REMOVE').remove_active = True + sub.menu( + MATERIAL_MT_POV_sss_presets.__name__, + text=MATERIAL_MT_POV_sss_presets.bl_label, + ) + sub.operator( + MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='ADD' + ) + sub.operator( + MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='REMOVE' + ).remove_active = True split = layout.split() @@ -1474,6 +1654,7 @@ class MATERIAL_PT_POV_sss(MaterialButtonsPanel, Panel): col.separator() col.prop(sss, "error_threshold", text="Error") + class MATERIAL_PT_POV_activate_node(MaterialButtonsPanel, Panel): """Use this class to define an activate pov nodes button.""" @@ -1485,16 +1666,23 @@ class MATERIAL_PT_POV_activate_node(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): engine = context.scene.render.engine - mat=context.material + mat = context.material ob = context.object - return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes) + return ( + mat + and mat.pov.type == "SURFACE" + and (engine in cls.COMPAT_ENGINES) + and not (mat.pov.material_use_nodes or mat.use_nodes) + ) def draw(self, context): layout = self.layout # layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') # the above replaced with a context hook below: - layout.operator("WM_OT_context_toggle", text="Use POV-Ray Nodes", icon='NODETREE').data_path = \ - "material.pov.material_use_nodes" + layout.operator( + "WM_OT_context_toggle", text="Use POV-Ray Nodes", icon='NODETREE' + ).data_path = "material.pov.material_use_nodes" + class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): """Use this class to show pov active node properties buttons.""" @@ -1507,10 +1695,14 @@ class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): engine = context.scene.render.engine - mat=context.material + mat = context.material ob = context.object - return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and mat.pov.material_use_nodes - + return ( + mat + and mat.pov.type == "SURFACE" + and (engine in cls.COMPAT_ENGINES) + and mat.pov.material_use_nodes + ) def draw(self, context): layout = self.layout @@ -1520,14 +1712,18 @@ class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): node = node_tree.nodes.active if mat.use_nodes: if node: - layout.prop(mat.pov,"material_active_node") - if node.bl_idname=="PovrayMaterialNode": + layout.prop(mat.pov, "material_active_node") + if node.bl_idname == "PovrayMaterialNode": layout.context_pointer_set("node", node) if hasattr(node, "draw_buttons_ext"): node.draw_buttons_ext(context, layout) elif hasattr(node, "draw_buttons"): node.draw_buttons(context, layout) - value_inputs = [socket for socket in node.inputs if socket.enabled and not socket.is_linked] + value_inputs = [ + socket + for socket in node.inputs + if socket.enabled and not socket.is_linked + ] if value_inputs: layout.separator() layout.label(text="Inputs:") @@ -1540,7 +1736,11 @@ class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): node.draw_buttons_ext(context, layout) elif hasattr(node, "draw_buttons"): node.draw_buttons(context, layout) - value_inputs = [socket for socket in node.inputs if socket.enabled and not socket.is_linked] + value_inputs = [ + socket + for socket in node.inputs + if socket.enabled and not socket.is_linked + ] if value_inputs: layout.separator() layout.label(text="Inputs:") @@ -1550,6 +1750,7 @@ class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): else: layout.label(text="No active nodes!") + class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): """Use this class to define standard material reflectivity (mirror) buttons.""" @@ -1558,12 +1759,15 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): bl_idname = "MATERIAL_PT_POV_raytrace_mirror" COMPAT_ENGINES = {'POVRAY_RENDER'} - @classmethod def poll(cls, context): mat = context.material engine = context.scene.render.engine - return check_material(mat) and (mat.pov.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) + return ( + check_material(mat) + and (mat.pov.type in {'SURFACE', 'WIRE'}) + and (engine in cls.COMPAT_ENGINES) + ) def draw_header(self, context): mat = context.material @@ -1574,7 +1778,9 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): def draw(self, context): layout = self.layout - mat = context.material #Formerly : #mat = active_node_mat(context.material) + mat = ( + context.material + ) # Formerly : #mat = active_node_mat(context.material) raym = mat.pov_raytrace_mirror layout.active = raym.use @@ -1588,7 +1794,7 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): col = split.column() col.prop(raym, "fresnel") sub = col.column() - sub.active = (raym.fresnel > 0.0) + sub.active = raym.fresnel > 0.0 sub.prop(raym, "fresnel_factor", text="Blend") split = layout.split() @@ -1599,7 +1805,7 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): col.prop(raym, "distance", text="Max Dist") col.separator() sub = col.split(factor=0.4) - sub.active = (raym.distance > 0.0) + sub.active = raym.distance > 0.0 sub.label(text="Fade To:") sub.prop(raym, "fade_to", text="") @@ -1607,11 +1813,12 @@ class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): col.label(text="Gloss:") col.prop(raym, "gloss_factor", text="Amount") sub = col.column() - sub.active = (raym.gloss_factor < 1.0) + sub.active = raym.gloss_factor < 1.0 sub.prop(raym, "gloss_threshold", text="Threshold") sub.prop(raym, "gloss_samples", text="Samples") sub.prop(raym, "gloss_anisotropic", text="Anisotropic") + class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): """Use this class to define pov material transparency (alpha) buttons.""" @@ -1622,7 +1829,11 @@ class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): def poll(cls, context): mat = context.material engine = context.scene.render.engine - return check_material(mat) and (mat.pov.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES) + return ( + check_material(mat) + and (mat.pov.type in {'SURFACE', 'WIRE'}) + and (engine in cls.COMPAT_ENGINES) + ) def draw_header(self, context): mat = context.material @@ -1634,7 +1845,7 @@ class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): layout = self.layout base_mat = context.material - mat = context.material#FORMERLY active_node_mat(context.material) + mat = context.material # FORMERLY active_node_mat(context.material) rayt = mat.pov_raytrace_transparency if simple_material(base_mat): @@ -1648,14 +1859,16 @@ class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): col = split.column() col.prop(mat.pov, "alpha") row = col.row() - row.active = (base_mat.pov.transparency_method != 'MASK') and (not mat.pov.use_shadeless) + row.active = (base_mat.pov.transparency_method != 'MASK') and ( + not mat.pov.use_shadeless + ) row.prop(mat.pov, "specular_alpha", text="Specular") col = split.column() - col.active = (not mat.pov.use_shadeless) + col.active = not mat.pov.use_shadeless col.prop(rayt, "fresnel") sub = col.column() - sub.active = (rayt.fresnel > 0.0) + sub.active = rayt.fresnel > 0.0 sub.prop(rayt, "fresnel_factor", text="Blend") if base_mat.pov.transparency_method == 'RAYTRACE': @@ -1678,6 +1891,7 @@ class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): sub.prop(rayt, "gloss_threshold", text="Threshold") sub.prop(rayt, "gloss_samples", text="Samples") + class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel): """Use this class to define more pov specific reflectivity buttons.""" @@ -1688,9 +1902,14 @@ class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): engine = context.scene.render.engine - mat=context.material + mat = context.material ob = context.object - return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes) + return ( + mat + and mat.pov.type == "SURFACE" + and (engine in cls.COMPAT_ENGINES) + and not (mat.pov.material_use_nodes or mat.use_nodes) + ) def draw(self, context): layout = self.layout @@ -1703,7 +1922,7 @@ class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel): col.prop(mat.pov, "irid_thickness", slider=True) col.prop(mat.pov, "irid_turbulence", slider=True) col.prop(mat.pov, "conserve_energy") - col2=col.split().column() + col2 = col.split().column() if not mat.pov_raytrace_mirror.use: col2.label(text="Please Check Mirror settings :") @@ -1714,6 +1933,8 @@ class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel): col2.label(text="The current Raytrace ") col2.label(text="Transparency IOR is: " + str(mat.pov.ior)) col2.prop(mat.pov, "mirror_metallic") + + ''' #group some native Blender (SSS) and POV (Fade)settings under such a parent panel? class MATERIAL_PT_POV_interior(MaterialButtonsPanel, Panel): @@ -1733,20 +1954,25 @@ class MATERIAL_PT_POV_interior(MaterialButtonsPanel, Panel): mat = context.material ''' + class MATERIAL_PT_POV_fade_color(MaterialButtonsPanel, Panel): """Use this class to define pov fading (absorption) color buttons.""" bl_label = "POV-Ray Absorption" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_parent_id = "material.pov_interior" + # bl_parent_id = "material.pov_interior" @classmethod def poll(cls, context): engine = context.scene.render.engine - mat=context.material + mat = context.material ob = context.object - return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes) - + return ( + mat + and mat.pov.type == "SURFACE" + and (engine in cls.COMPAT_ENGINES) + and not (mat.pov.material_use_nodes or mat.use_nodes) + ) def draw_header(self, context): mat = context.material @@ -1771,21 +1997,29 @@ class MATERIAL_PT_POV_caustics(MaterialButtonsPanel, Panel): bl_label = "Caustics" COMPAT_ENGINES = {'POVRAY_RENDER'} - @classmethod def poll(cls, context): engine = context.scene.render.engine - mat=context.material + mat = context.material ob = context.object - return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes) - + return ( + mat + and mat.pov.type == "SURFACE" + and (engine in cls.COMPAT_ENGINES) + and not (mat.pov.material_use_nodes or mat.use_nodes) + ) def draw_header(self, context): mat = context.material if mat.pov.caustics_enable: - self.layout.prop(mat.pov, "caustics_enable", text="", icon="PMARKER_SEL" ) + self.layout.prop( + mat.pov, "caustics_enable", text="", icon="PMARKER_SEL" + ) else: - self.layout.prop(mat.pov, "caustics_enable", text="", icon="PMARKER" ) + self.layout.prop( + mat.pov, "caustics_enable", text="", icon="PMARKER" + ) + def draw(self, context): layout = self.layout @@ -1806,12 +2040,16 @@ class MATERIAL_PT_POV_caustics(MaterialButtonsPanel, Panel): col.prop(mat.pov, "photons_dispersion_samples", slider=True) col.prop(mat.pov, "photons_reflection") - if not mat.pov.refraction_caustics and not mat.pov.photons_reflection: + if ( + not mat.pov.refraction_caustics + and not mat.pov.photons_reflection + ): col = layout.column() col.alignment = 'CENTER' col.label(text="Caustics override is on, ") col.label(text="but you didn't chose any !") + class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): """Use this class to define Blender strand antialiasing buttons.""" @@ -1823,7 +2061,11 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): def poll(cls, context): mat = context.material engine = context.scene.render.engine - return mat and (mat.pov.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES) + return ( + mat + and (mat.pov.type in {'SURFACE', 'WIRE', 'HALO'}) + and (engine in cls.COMPAT_ENGINES) + ) def draw(self, context): layout = self.layout @@ -1841,7 +2083,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): sub.prop(tan, "size_min", text="Minimum") sub.prop(tan, "use_blender_units") sub = col.column() - sub.active = (not mat.pov.use_shadeless) + sub.active = not mat.pov.use_shadeless sub.prop(tan, "use_tangent_shading") col.prop(tan, "shape") @@ -1850,23 +2092,25 @@ class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): col.prop(tan, "width_fade") ob = context.object if ob and ob.type == 'MESH': - col.prop_search(tan, "uv_layer", ob.data, "tessface_uv_textures", text="") + col.prop_search( + tan, "uv_layer", ob.data, "tessface_uv_textures", text="" + ) else: col.prop(tan, "uv_layer", text="") col.separator() sub = col.column() - sub.active = (not mat.pov.use_shadeless) + sub.active = not mat.pov.use_shadeless sub.label(text="Surface diffuse:") sub = col.column() sub.prop(tan, "blend_distance", text="Distance") + class MATERIAL_PT_POV_replacement_text(MaterialButtonsPanel, Panel): """Use this class to define pov custom code declared name field.""" bl_label = "Custom POV Code" COMPAT_ENGINES = {'POVRAY_RENDER'} - def draw(self, context): layout = self.layout @@ -1876,6 +2120,7 @@ class MATERIAL_PT_POV_replacement_text(MaterialButtonsPanel, Panel): col.label(text="Replace properties with:") col.prop(mat.pov, "replacement_text", text="") + class TEXTURE_MT_POV_specials(bpy.types.Menu): """Use this class to define pov texture slot operations buttons.""" @@ -1888,14 +2133,18 @@ class TEXTURE_MT_POV_specials(bpy.types.Menu): layout.operator("texture.slot_copy", icon='COPYDOWN') layout.operator("texture.slot_paste", icon='PASTEDOWN') + class TEXTURE_UL_POV_texture_slots(bpy.types.UIList): - """Use this class to show pov texture slots list.""" # used? + """Use this class to show pov texture slots list.""" # used? COMPAT_ENGINES = {'POVRAY_RENDER'} - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + + def draw_item( + self, context, layout, data, item, icon, active_data, active_propname + ): ob = data slot = item - #ma = slot.name + # ma = slot.name # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. if self.layout_type in {'DEFAULT', 'COMPACT'}: # You should always start your row layout by a label (icon + text), or a non-embossed text field, @@ -1903,13 +2152,17 @@ class TEXTURE_UL_POV_texture_slots(bpy.types.UIList): # We use icon_value of label, as our given icon is an integer value, not an enum ID. # Note "data" names should never be translated! if slot: - layout.prop(item, "texture", text="", emboss=False, icon='TEXTURE') + layout.prop( + item, "texture", text="", emboss=False, icon='TEXTURE' + ) else: layout.label(text="New", translate=False, icon_value=icon) # 'GRID' layout type should be as compact as possible (typically a single icon!). elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) + + ''' class MATERIAL_TEXTURE_SLOTS_UL_List(UIList): """Texture Slots UIList.""" @@ -1933,39 +2186,50 @@ class MATERIAL_TEXTURE_SLOTS_UL_List(UIList): layout.alignment = 'CENTER' layout.label("", icon = custom_icon) ''' -class WORLD_TEXTURE_SLOTS_UL_List(UIList): - """Use this class to show pov texture slots list.""" # XXX Not used yet - - def draw_item(self, context, layout, world, item, icon, active_data, - active_texture_index, index): - world = context.world#.pov +class WORLD_TEXTURE_SLOTS_UL_List(UIList): + """Use this class to show pov texture slots list.""" # XXX Not used yet + + def draw_item( + self, + context, + layout, + world, + item, + icon, + active_data, + active_texture_index, + index, + ): + world = context.world # .pov active_data = world.pov - #tex = context.texture #may be needed later? - + # tex = context.texture #may be needed later? # We could write some code to decide which icon to use here... custom_icon = 'TEXTURE' # Make sure your code supports all 3 layout types if self.layout_type in {'DEFAULT', 'COMPACT'}: - layout.label(item.name, icon = custom_icon) + layout.label(item.name, icon=custom_icon) elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' - layout.label("", icon = custom_icon) + layout.label("", icon=custom_icon) + class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList): """Use this class to show pov texture slots list.""" -# texture_slots: + # texture_slots: index: bpy.props.IntProperty(name='index') - #foo = random prop - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + # foo = random prop + def draw_item( + self, context, layout, data, item, icon, active_data, active_propname + ): ob = data slot = item - #ma = slot.name + # ma = slot.name # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. if self.layout_type in {'DEFAULT', 'COMPACT'}: # You should always start your row layout by a label (icon + text), or a non-embossed text field, @@ -1973,7 +2237,9 @@ class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList): # We use icon_value of label, as our given icon is an integer value, not an enum ID. # Note "data" names should never be translated! if slot: - layout.prop(item, "texture", text="", emboss=False, icon='TEXTURE') + layout.prop( + item, "texture", text="", emboss=False, icon='TEXTURE' + ) else: layout.label(text="New", translate=False, icon_value=icon) # 'GRID' layout type should be as compact as possible (typically a single icon!). @@ -1981,6 +2247,7 @@ class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(bpy.types.UIList): layout.alignment = 'CENTER' layout.label(text="", icon_value=icon) + class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): """Use this class to show pov texture context buttons.""" @@ -1991,18 +2258,19 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): @classmethod def poll(cls, context): engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): # return False - return ((context.material or - context.world or - context.light or - context.texture or - context.line_style or - context.particle_system or - isinstance(context.space_data.pin_id, ParticleSettings) or - context.texture_user) and - (engine in cls.COMPAT_ENGINES)) + return ( + context.material + or context.world + or context.light + or context.texture + or context.line_style + or context.particle_system + or isinstance(context.space_data.pin_id, ParticleSettings) + or context.texture_user + ) and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -2010,12 +2278,21 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): scene = context.scene layout.prop(scene, "texture_context", expand=True) if scene.texture_context == 'MATERIAL': - mat = context.scene.view_layers["View Layer"].objects.active.active_material + mat = context.scene.view_layers[ + "View Layer" + ].objects.active.active_material row = layout.row() - row.template_list("MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist", "", mat, "pov_texture_slots", mat.pov, "active_texture_index") + row.template_list( + "MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist", + "", + mat, + "pov_texture_slots", + mat.pov, + "active_texture_index", + ) col = row.column(align=True) - col.operator("pov.textureslotadd",icon='ADD',text='') - col.operator("pov.textureslotremove",icon='REMOVE',text='') + col.operator("pov.textureslotadd", icon='ADD', text='') + col.operator("pov.textureslotremove", icon='REMOVE', text='') col.separator() if mat.pov_texture_slots: @@ -2023,12 +2300,15 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): slot = mat.pov_texture_slots[index] povtex = slot.name tex = bpy.data.textures[povtex] - col.prop(tex,'use_fake_user',text = '') + col.prop(tex, 'use_fake_user', text='') layout.label(text='Find texture:') - layout.prop_search(slot,'texture_search',bpy.data,'textures',text='') + layout.prop_search( + slot, 'texture_search', bpy.data, 'textures', text='' + ) # else: - # for i in range(18): # length of material texture slots - # mat.pov_texture_slots.add() + # for i in range(18): # length of material texture slots + # mat.pov_texture_slots.add() + # Commented out below is a reminder of what existed in Blender Internal # attributes need to be recreated @@ -2138,6 +2418,8 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): else: split.label(text="Type:") ''' + + class TEXTURE_PT_colors(TextureButtonsPanel, Panel): """Use this class to show pov color ramps.""" @@ -2172,6 +2454,7 @@ class TEXTURE_PT_colors(TextureButtonsPanel, Panel): col = layout.column() col.prop(tex, "use_clamp", text="Clamp") + # Texture Slot Panels # @@ -2184,9 +2467,9 @@ class MATERIAL_OT_POV_texture_slot_add(Operator): bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} - def execute(self,context): + def execute(self, context): - tex = bpy.data.textures.new(name = 'Texture',type = 'IMAGE') + tex = bpy.data.textures.new(name='Texture', type='IMAGE') tex.use_fake_user = True ob = context.scene.view_layers["View Layer"].objects.active slot = ob.active_material.pov_texture_slots.add() @@ -2205,7 +2488,7 @@ class MATERIAL_OT_POV_texture_slot_remove(Operator): bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} - def execute(self,context): + def execute(self, context): pass # tex = bpy.data.textures.new() # tex_slot = context.object.active_material.pov_texture_slots.add() @@ -2213,6 +2496,7 @@ class MATERIAL_OT_POV_texture_slot_remove(Operator): return {'FINISHED'} + class TextureSlotPanel(TextureButtonsPanel): """Use this class to show pov texture slots panel.""" @@ -2224,7 +2508,10 @@ class TextureSlotPanel(TextureButtonsPanel): return False engine = context.scene.render.engine - return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES) + return TextureButtonsPanel.poll(cls, context) and ( + engine in cls.COMPAT_ENGINES + ) + class TEXTURE_PT_POV_type(TextureButtonsPanel, Panel): """Use this class to define pov texture type buttons.""" @@ -2244,7 +2531,7 @@ class TEXTURE_PT_POV_type(TextureButtonsPanel, Panel): # row = layout.row() # row.template_list("WORLD_TEXTURE_SLOTS_UL_List", "texture_slots", world, - # world.texture_slots, world, "active_texture_index") + # world.texture_slots, world, "active_texture_index") class TEXTURE_PT_POV_preview(TextureButtonsPanel, Panel): @@ -2259,9 +2546,13 @@ class TEXTURE_PT_POV_preview(TextureButtonsPanel, Panel): engine = context.scene.render.engine if not hasattr(context, "pov_texture_slot"): return False - tex=context.texture - mat=bpy.context.active_object.active_material - return (tex and (tex.pov.tex_pattern_type != 'emulator') and (engine in cls.COMPAT_ENGINES)) + tex = context.texture + mat = bpy.context.active_object.active_material + return ( + tex + and (tex.pov.tex_pattern_type != 'emulator') + and (engine in cls.COMPAT_ENGINES) + ) def draw(self, context): tex = context.texture @@ -2269,7 +2560,7 @@ class TEXTURE_PT_POV_preview(TextureButtonsPanel, Panel): idblock = pov_context_tex_datablock(context) layout = self.layout # if idblock: - # layout.template_preview(tex, parent=idblock, slot=slot) + # layout.template_preview(tex, parent=idblock, slot=slot) if tex.pov.tex_pattern_type != 'emulator': layout.operator("tex.preview_update") else: @@ -2281,14 +2572,17 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): bl_label = "POV Pattern Options" COMPAT_ENGINES = {'POVRAY_RENDER'} + def draw(self, context): mat = bpy.context.active_object.active_material layout = self.layout tex = context.texture - align=True + 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") + 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': @@ -2304,29 +2598,32 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): 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 = 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'}: + 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': + 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 = 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 = col.row() row.prop(tex.pov, "f_ior", text="Interior") row.prop(tex.pov, "f_ior_fac", text="Factor I") - row=col.row() + 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': @@ -2336,7 +2633,9 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): 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") + 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") @@ -2365,42 +2664,105 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): 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": + 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"}: + 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"}: + 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"}: + 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"}: + 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"}: + 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"}: + 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"}: + 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 @@ -2416,37 +2778,40 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): 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) + 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) + 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) + 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) + 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 = layout.row(align=align) row.prop(tex.pov, "func_P8", text="P8") row.prop(tex.pov, "func_P9", text="P9") - ###################################################End Patterns############################ - + ###################################################End Patterns############################ - layout.prop(tex.pov, "warp_types", text="Warp types") #warp + 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") + 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") @@ -2454,38 +2819,39 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): row.prop(tex.pov, "modifier_frequency", text="Frequency") row.prop(tex.pov, "modifier_phase", text="Phase") - row=layout.row() + row = layout.row() row.label(text="Offset:") row.label(text="Scale:") row.label(text="Rotate:") - col=layout.column(align=align) - row=col.row() + 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 = 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 = 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 = layout.row() row.label(text="Turbulence:") - col=layout.column(align=align) - row=col.row() + 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 = col.row() row.prop(tex.pov, "warp_turbulence_y", text="Y") row.prop(tex.pov, "modifier_lambda", text="Lambda") - row=col.row() + row = col.row() row.prop(tex.pov, "warp_turbulence_z", text="Z") row.prop(tex.pov, "modifier_omega", text="Omega") + class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): """Use this class to define pov texture influence buttons.""" @@ -2497,14 +2863,17 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): @classmethod def poll(cls, context): idblock = pov_context_tex_datablock(context) - if (isinstance(idblock, Brush) and bpy.context.scene.texture_context == 'OTHER'): #XXX replace by bpy.types.Brush? + if ( + isinstance(idblock, Brush) + and bpy.context.scene.texture_context == 'OTHER' + ): # XXX replace by isinstance(idblock, bpy.types.Brush) and ... return False # if not getattr(context, "pov_texture_slot", None): - # return False + # return False engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES def draw(self, context): @@ -2514,8 +2883,13 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): # tex = context.pov_texture_slot mat = bpy.context.active_object.active_material - texslot = mat.pov_texture_slots[mat.active_texture_index] #bpy.data.textures[mat.active_texture_index] - tex = bpy.data.textures[mat.pov_texture_slots[mat.active_texture_index].texture] + texslot = mat.pov_texture_slots[ + mat.active_texture_index + ] # bpy.data.textures[mat.active_texture_index] + tex = bpy.data.textures[ + mat.pov_texture_slots[mat.active_texture_index].texture + ] + def factor_but(layout, toggle, factor, name): row = layout.row(align=True) row.prop(texslot, toggle, text="") @@ -2534,15 +2908,33 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): col = split.column() col.label(text="Diffuse:") - factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity") - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") + factor_but( + col, "use_map_diffuse", "diffuse_factor", "Intensity" + ) + factor_but( + col, + "use_map_color_diffuse", + "diffuse_color_factor", + "Color", + ) factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - factor_but(col, "use_map_translucency", "translucency_factor", "Translucency") + factor_but( + col, + "use_map_translucency", + "translucency_factor", + "Translucency", + ) col.label(text="Specular:") - factor_but(col, "use_map_specular", "specular_factor", "Intensity") - factor_but(col, "use_map_color_spec", "specular_color_factor", "Color") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") + factor_but( + col, "use_map_specular", "specular_factor", "Intensity" + ) + factor_but( + col, "use_map_color_spec", "specular_color_factor", "Color" + ) + factor_but( + col, "use_map_hardness", "hardness_factor", "Hardness" + ) col = split.column() col.label(text="Shading:") @@ -2553,29 +2945,47 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): col.label(text="Geometry:") # XXX replace 'or' when displacement is fixed to not rely on normal influence value. - sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal") - sub_tmp.active = (texslot.use_map_normal or texslot.use_map_displacement) + sub_tmp = factor_but( + col, "use_map_normal", "normal_factor", "Normal" + ) + sub_tmp.active = ( + texslot.use_map_normal or texslot.use_map_displacement + ) # END XXX factor_but(col, "use_map_warp", "warp_factor", "Warp") - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") + factor_but( + col, + "use_map_displacement", + "displacement_factor", + "Displace", + ) # ~ sub = col.column() # ~ sub.active = texslot.use_map_translucency or texslot.map_emit or texslot.map_alpha or texslot.map_raymir or texslot.map_hardness or texslot.map_ambient or texslot.map_specularity or texslot.map_reflection or texslot.map_mirror - #~ sub.prop(texslot, "default_value", text="Amount", slider=True) + # ~ sub.prop(texslot, "default_value", text="Amount", slider=True) elif idblock.pov.type == 'HALO': layout.label(text="Halo:") split = layout.split() col = split.column() - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") + factor_but( + col, + "use_map_color_diffuse", + "diffuse_color_factor", + "Color", + ) factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") col = split.column() factor_but(col, "use_map_raymir", "raymir_factor", "Size") - factor_but(col, "use_map_hardness", "hardness_factor", "Hardness") - factor_but(col, "use_map_translucency", "translucency_factor", "Add") + factor_but( + col, "use_map_hardness", "hardness_factor", "Hardness" + ) + factor_but( + col, "use_map_translucency", "translucency_factor", "Add" + ) elif idblock.pov.type == 'VOLUME': layout.label(text="Volume:") @@ -2583,15 +2993,36 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): col = split.column() factor_but(col, "use_map_density", "density_factor", "Density") - factor_but(col, "use_map_emission", "emission_factor", "Emission") - factor_but(col, "use_map_scatter", "scattering_factor", "Scattering") - factor_but(col, "use_map_reflect", "reflection_factor", "Reflection") + factor_but( + col, "use_map_emission", "emission_factor", "Emission" + ) + factor_but( + col, "use_map_scatter", "scattering_factor", "Scattering" + ) + factor_but( + col, "use_map_reflect", "reflection_factor", "Reflection" + ) col = split.column() col.label(text=" ") - factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color") - factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color") - factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color") + factor_but( + col, + "use_map_color_emission", + "emission_color_factor", + "Emission Color", + ) + factor_but( + col, + "use_map_color_transmission", + "transmission_color_factor", + "Transmission Color", + ) + factor_but( + col, + "use_map_color_reflection", + "reflection_color_factor", + "Reflection Color", + ) layout.label(text="Geometry:") @@ -2601,7 +3032,12 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): factor_but(col, "use_map_warp", "warp_factor", "Warp") col = split.column() - factor_but(col, "use_map_displacement", "displacement_factor", "Displace") + factor_but( + col, + "use_map_displacement", + "displacement_factor", + "Displace", + ) elif isinstance(idblock, Light): split = layout.split() @@ -2620,8 +3056,12 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): factor_but(col, "use_map_horizon", "horizon_factor", "Horizon") col = split.column() - factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up") - factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down") + factor_but( + col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up" + ) + factor_but( + col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down" + ) elif isinstance(idblock, ParticleSettings): split = layout.split() @@ -2649,15 +3089,21 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): factor_but(col, "use_map_twist", "twist_factor", "Twist") col = split.column() - factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude") - factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency") + factor_but( + col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude" + ) + factor_but( + col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency" + ) factor_but(col, "use_map_rough", "rough_factor", "Rough") elif isinstance(idblock, FreestyleLineStyle): split = layout.split() col = split.column() - factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") + factor_but( + col, "use_map_color_diffuse", "diffuse_color_factor", "Color" + ) col = split.column() factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") @@ -2676,8 +3122,8 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): # col.prop(tex, "invert", text="Negative") #deprecated since 2.8 # col.prop(tex, "use_stencil") #deprecated since 2.8 - #if isinstance(idblock, (Material, World)): - #col.prop(tex, "default_value", text="DVar", slider=True) + # if isinstance(idblock, (Material, World)): + # col.prop(tex, "default_value", text="DVar", slider=True) class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel): @@ -2689,7 +3135,9 @@ class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel): def draw_header(self, context): tex = context.texture - self.layout.prop(tex.pov, "tex_gamma_enable", text="", icon='SEQ_LUMA_WAVEFORM') + self.layout.prop( + tex.pov, "tex_gamma_enable", text="", icon='SEQ_LUMA_WAVEFORM' + ) def draw(self, context): layout = self.layout @@ -2699,19 +3147,20 @@ class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel): layout.active = tex.pov.tex_gamma_enable layout.prop(tex.pov, "tex_gamma_value", text="Gamma Value") -#commented out below UI for texture only custom code inside exported material: + +# commented out below UI for texture only custom code inside exported material: # class TEXTURE_PT_povray_replacement_text(TextureButtonsPanel, Panel): - # bl_label = "Custom POV Code" - # COMPAT_ENGINES = {'POVRAY_RENDER'} +# bl_label = "Custom POV Code" +# COMPAT_ENGINES = {'POVRAY_RENDER'} - # def draw(self, context): - # layout = self.layout +# def draw(self, context): +# layout = self.layout - # tex = context.texture +# tex = context.texture - # col = layout.column() - # col.label(text="Replace properties with:") - # col.prop(tex.pov, "replacement_text", text="") +# col = layout.column() +# col.label(text="Replace properties with:") +# col.prop(tex.pov, "replacement_text", text="") class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel): @@ -2724,7 +3173,7 @@ class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel): def poll(cls, context): engine = context.scene.render.engine - return (engine in cls.COMPAT_ENGINES) + return engine in cls.COMPAT_ENGINES def draw(self, context): layout = self.layout @@ -2740,43 +3189,50 @@ class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel): col.label(text="Photons:") col.prop(obj.pov, "collect_photons", text="Receive Photon Caustics") if obj.pov.collect_photons: - col.prop(obj.pov, "spacing_multiplier", text="Photons Spacing Multiplier") + col.prop( + obj.pov, "spacing_multiplier", text="Photons Spacing Multiplier" + ) split = layout.split() col = split.column() - col.prop(obj.pov,"hollow") - col.prop(obj.pov,"double_illuminate") - + col.prop(obj.pov, "hollow") + col.prop(obj.pov, "double_illuminate") if obj.type == 'META' or obj.pov.curveshape == 'lathe': - #if obj.pov.curveshape == 'sor' - col.prop(obj.pov,"sturm") - col.prop(obj.pov,"no_shadow") - col.prop(obj.pov,"no_image") - col.prop(obj.pov,"no_reflection") - col.prop(obj.pov,"no_radiosity") - col.prop(obj.pov,"inverse") - col.prop(obj.pov,"hierarchy") + # if obj.pov.curveshape == 'sor' + col.prop(obj.pov, "sturm") + col.prop(obj.pov, "no_shadow") + col.prop(obj.pov, "no_image") + col.prop(obj.pov, "no_reflection") + col.prop(obj.pov, "no_radiosity") + col.prop(obj.pov, "inverse") + col.prop(obj.pov, "hierarchy") # col.prop(obj.pov,"boundorclip",text="Bound / Clip") # if obj.pov.boundorclip != "none": - # col.prop_search(obj.pov,"boundorclipob",context.blend_data,"objects",text="Object") - # text = "Clipped by" - # if obj.pov.boundorclip == "clipped_by": - # text = "Bounded by" - # col.prop(obj.pov,"addboundorclip",text=text) + # col.prop_search(obj.pov,"boundorclipob",context.blend_data,"objects",text="Object") + # text = "Clipped by" + # if obj.pov.boundorclip == "clipped_by": + # text = "Bounded by" + # col.prop(obj.pov,"addboundorclip",text=text) + class OBJECT_PT_POV_obj_sphere(PovDataButtonsPanel, Panel): """Use this class to define pov sphere primitive parameters buttons.""" bl_label = "POV Sphere" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'SPHERE' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'SPHERE' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2786,18 +3242,29 @@ class OBJECT_PT_POV_obj_sphere(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'SPHERE': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) col.label(text="Sphere radius: " + str(obj.pov.sphere_radius)) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.sphere_update", text="Update", icon="SHADING_RENDERED" + ) - layout.operator("pov.sphere_update", text="Update",icon="SHADING_RENDERED") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.pov, "sphere_radius", text="Radius of Sphere") @@ -2806,12 +3273,17 @@ class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel): bl_label = "POV Cylinder" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'CYLINDER' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'CYLINDER' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2821,33 +3293,55 @@ class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'CYLINDER': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') - col.label(text="Cylinder radius: " + str(obj.pov.cylinder_radius)) - col.label(text="Cylinder cap location: " + str(obj.pov.cylinder_location_cap)) + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) + col.label( + text="Cylinder radius: " + str(obj.pov.cylinder_radius) + ) + col.label( + text="Cylinder cap location: " + + str(obj.pov.cylinder_location_cap) + ) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.cylinder_update", text="Update", icon="MESH_CYLINDER" + ) - layout.operator("pov.cylinder_update", text="Update",icon="MESH_CYLINDER") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.pov, "cylinder_radius") col.prop(obj.pov, "cylinder_location_cap") + class OBJECT_PT_POV_obj_cone(PovDataButtonsPanel, Panel): """Use this class to define pov cone primitive parameters buttons.""" bl_label = "POV Cone" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'CONE' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'CONE' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2857,36 +3351,63 @@ class OBJECT_PT_POV_obj_cone(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'CONE': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') - col.label(text="Cone base radius: " + str(obj.pov.cone_base_radius)) - col.label(text="Cone cap radius: " + str(obj.pov.cone_cap_radius)) - col.label(text="Cone proxy segments: " + str(obj.pov.cone_segments)) + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) + col.label( + text="Cone base radius: " + str(obj.pov.cone_base_radius) + ) + col.label( + text="Cone cap radius: " + str(obj.pov.cone_cap_radius) + ) + col.label( + text="Cone proxy segments: " + str(obj.pov.cone_segments) + ) col.label(text="Cone height: " + str(obj.pov.cone_height)) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.cone_update", text="Update", icon="MESH_CONE" + ) - layout.operator("pov.cone_update", text="Update",icon="MESH_CONE") - - #col.label(text="Parameters:") - col.prop(obj.pov, "cone_base_radius", text="Radius of Cone Base") + # col.label(text="Parameters:") + col.prop( + obj.pov, "cone_base_radius", text="Radius of Cone Base" + ) col.prop(obj.pov, "cone_cap_radius", text="Radius of Cone Cap") - col.prop(obj.pov, "cone_segments", text="Segmentation of Cone proxy") + col.prop( + obj.pov, "cone_segments", text="Segmentation of Cone proxy" + ) col.prop(obj.pov, "cone_height", text="Height of the cone") + class OBJECT_PT_POV_obj_superellipsoid(PovDataButtonsPanel, Panel): """Use this class to define pov superellipsoid primitive parameters buttons.""" bl_label = "POV Superquadric ellipsoid" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'SUPERELLIPSOID' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'SUPERELLIPSOID' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2896,21 +3417,34 @@ class OBJECT_PT_POV_obj_superellipsoid(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'SUPERELLIPSOID': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) col.label(text="Radial segmentation: " + str(obj.pov.se_u)) col.label(text="Lateral segmentation: " + str(obj.pov.se_v)) col.label(text="Ring shape: " + str(obj.pov.se_n1)) col.label(text="Cross-section shape: " + str(obj.pov.se_n2)) col.label(text="Fill up and down: " + str(obj.pov.se_edit)) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.superellipsoid_update", + text="Update", + icon="MOD_SUBSURF", + ) - layout.operator("pov.superellipsoid_update", text="Update",icon="MOD_SUBSURF") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.pov, "se_u") col.prop(obj.pov, "se_v") col.prop(obj.pov, "se_n1") @@ -2923,12 +3457,17 @@ class OBJECT_PT_POV_obj_torus(PovDataButtonsPanel, Panel): bl_label = "POV Torus" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'TORUS' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'TORUS' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2938,36 +3477,65 @@ class OBJECT_PT_POV_obj_torus(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'TORUS': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') - col.label(text="Torus major radius: " + str(obj.pov.torus_major_radius)) - col.label(text="Torus minor radius: " + str(obj.pov.torus_minor_radius)) - col.label(text="Torus major segments: " + str(obj.pov.torus_major_segments)) - col.label(text="Torus minor segments: " + str(obj.pov.torus_minor_segments)) + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) + col.label( + text="Torus major radius: " + + str(obj.pov.torus_major_radius) + ) + col.label( + text="Torus minor radius: " + + str(obj.pov.torus_minor_radius) + ) + col.label( + text="Torus major segments: " + + str(obj.pov.torus_major_segments) + ) + col.label( + text="Torus minor segments: " + + str(obj.pov.torus_minor_segments) + ) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.torus_update", text="Update", icon="MESH_TORUS" + ) - layout.operator("pov.torus_update", text="Update",icon="MESH_TORUS") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.pov, "torus_major_radius") col.prop(obj.pov, "torus_minor_radius") col.prop(obj.pov, "torus_major_segments") col.prop(obj.pov, "torus_minor_segments") + class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel): """Use this class to define pov supertorus primitive parameters buttons.""" bl_label = "POV SuperTorus" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'SUPERTORUS' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'SUPERTORUS' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -2977,29 +3545,62 @@ class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'SUPERTORUS': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') - col.label(text="SuperTorus major radius: " + str(obj.pov.st_major_radius)) - col.label(text="SuperTorus minor radius: " + str(obj.pov.st_minor_radius)) - col.label(text="SuperTorus major segments: " + str(obj.pov.st_u)) - col.label(text="SuperTorus minor segments: " + str(obj.pov.st_v)) - - col.label(text="SuperTorus Ring Manipulator: " + str(obj.pov.st_ring)) - col.label(text="SuperTorus Cross Manipulator: " + str(obj.pov.st_cross)) - col.label(text="SuperTorus Internal And External radii: " + str(obj.pov.st_ie)) - - col.label(text="SuperTorus accuracy: " + str(ob.pov.st_accuracy)) - col.label(text="SuperTorus max gradient: " + str(ob.pov.st_max_gradient)) - + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) + col.label( + text="SuperTorus major radius: " + + str(obj.pov.st_major_radius) + ) + col.label( + text="SuperTorus minor radius: " + + str(obj.pov.st_minor_radius) + ) + col.label( + text="SuperTorus major segments: " + str(obj.pov.st_u) + ) + col.label( + text="SuperTorus minor segments: " + str(obj.pov.st_v) + ) + + col.label( + text="SuperTorus Ring Manipulator: " + str(obj.pov.st_ring) + ) + col.label( + text="SuperTorus Cross Manipulator: " + + str(obj.pov.st_cross) + ) + col.label( + text="SuperTorus Internal And External radii: " + + str(obj.pov.st_ie) + ) + + col.label( + text="SuperTorus accuracy: " + str(ob.pov.st_accuracy) + ) + col.label( + text="SuperTorus max gradient: " + + str(ob.pov.st_max_gradient) + ) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters + layout.operator( + "pov.supertorus_update", text="Update", icon="MESH_TORUS" + ) - layout.operator("pov.supertorus_update", text="Update",icon="MESH_TORUS") - - #col.label(text="Parameters:") + # col.label(text="Parameters:") col.prop(obj.pov, "st_major_radius") col.prop(obj.pov, "st_minor_radius") col.prop(obj.pov, "st_u") @@ -3007,21 +3608,27 @@ class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel): col.prop(obj.pov, "st_ring") col.prop(obj.pov, "st_cross") col.prop(obj.pov, "st_ie") - #col.prop(obj.pov, "st_edit") #? + # col.prop(obj.pov, "st_edit") #? col.prop(obj.pov, "st_accuracy") col.prop(obj.pov, "st_max_gradient") + class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel): """Use this class to define pov parametric surface primitive parameters buttons.""" bl_label = "POV Parametric surface" COMPAT_ENGINES = {'POVRAY_RENDER'} - #bl_options = {'HIDE_HEADER'} + # bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): engine = context.scene.render.engine obj = context.object - return (obj and obj.pov.object_as == 'PARAMETRIC' and (engine in cls.COMPAT_ENGINES)) + return ( + obj + and obj.pov.object_as == 'PARAMETRIC' + and (engine in cls.COMPAT_ENGINES) + ) + def draw(self, context): layout = self.layout @@ -3031,7 +3638,12 @@ class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel): if obj.pov.object_as == 'PARAMETRIC': if obj.pov.unlock_parameters == False: - col.prop(obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Exported parameters below", + icon='LOCKED', + ) col.label(text="Minimum U: " + str(obj.pov.u_min)) col.label(text="Minimum V: " + str(obj.pov.v_min)) col.label(text="Maximum U: " + str(obj.pov.u_max)) @@ -3041,12 +3653,18 @@ class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel): col.label(text="Z Function: " + str(obj.pov.x_eq)) else: - col.prop(obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED') + col.prop( + obj.pov, + "unlock_parameters", + text="Edit exported parameters", + icon='UNLOCKED', + ) col.label(text="3D view proxy may get out of synch") col.active = obj.pov.unlock_parameters - - layout.operator("pov.parametric_update", text="Update",icon="SCRIPTPLUGINS") + layout.operator( + "pov.parametric_update", text="Update", icon="SCRIPTPLUGINS" + ) col.prop(obj.pov, "u_min", text="Minimum U") col.prop(obj.pov, "v_min", text="Minimum V") @@ -3072,6 +3690,7 @@ class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel): col.label(text="Replace properties with:") col.prop(obj.pov, "replacement_text", text="") + ############################################################################### # Add Povray Objects ############################################################################### @@ -3079,6 +3698,7 @@ class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel): class VIEW_MT_POV_primitives_add(bpy.types.Menu): """Define the primitives menu with presets""" + bl_idname = "VIEW_MT_POV_primitives_add" bl_label = "Povray" COMPAT_ENGINES = {'POVRAY_RENDER'} @@ -3086,13 +3706,16 @@ class VIEW_MT_POV_primitives_add(bpy.types.Menu): @classmethod def poll(cls, context): engine = context.scene.render.engine - return (engine == 'POVRAY_RENDER') + return engine == 'POVRAY_RENDER' - def draw(self,context): + def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.menu(VIEW_MT_POV_Basic_Shapes.bl_idname, text = "Primitives",icon="GROUP") - layout.menu(VIEW_MT_POV_import.bl_idname, text = "Import",icon="IMPORT") + layout.menu( + VIEW_MT_POV_Basic_Shapes.bl_idname, text="Primitives", icon="GROUP" + ) + layout.menu(VIEW_MT_POV_import.bl_idname, text="Import", icon="IMPORT") + class VIEW_MT_POV_Basic_Shapes(bpy.types.Menu): """Use this class to sort simple primitives menu entries.""" @@ -3100,48 +3723,81 @@ class VIEW_MT_POV_Basic_Shapes(bpy.types.Menu): bl_idname = "POVRAY_MT_basic_shape_tools" bl_label = "Basic_shapes" - def draw(self,context): + def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("pov.addplane", text="Infinite Plane",icon = 'MESH_PLANE') - layout.operator("pov.addbox", text="Box",icon = 'MESH_CUBE') - layout.operator("pov.addsphere", text="Sphere",icon = 'SHADING_RENDERED') - layout.operator("pov.addcylinder", text="Cylinder",icon="MESH_CYLINDER") - layout.operator("pov.cone_add", text="Cone",icon="MESH_CONE") - layout.operator("pov.addtorus", text="Torus",icon = 'MESH_TORUS') + layout.operator( + "pov.addplane", text="Infinite Plane", icon='MESH_PLANE' + ) + layout.operator("pov.addbox", text="Box", icon='MESH_CUBE') + layout.operator("pov.addsphere", text="Sphere", icon='SHADING_RENDERED') + layout.operator( + "pov.addcylinder", text="Cylinder", icon="MESH_CYLINDER" + ) + layout.operator("pov.cone_add", text="Cone", icon="MESH_CONE") + layout.operator("pov.addtorus", text="Torus", icon='MESH_TORUS') layout.separator() - layout.operator("pov.addrainbow", text="Rainbow",icon="COLOR") - layout.operator("pov.addlathe", text="Lathe",icon = 'MOD_SCREW') - layout.operator("pov.addprism", text="Prism",icon = 'MOD_SOLIDIFY') - layout.operator("pov.addsuperellipsoid", text="Superquadric Ellipsoid",icon = 'MOD_SUBSURF') - layout.operator("pov.addheightfield", text="Height Field",icon="RNDCURVE") - layout.operator("pov.addspheresweep", text="Sphere Sweep",icon = 'FORCE_CURVE') + layout.operator("pov.addrainbow", text="Rainbow", icon="COLOR") + layout.operator("pov.addlathe", text="Lathe", icon='MOD_SCREW') + layout.operator("pov.addprism", text="Prism", icon='MOD_SOLIDIFY') + layout.operator( + "pov.addsuperellipsoid", + text="Superquadric Ellipsoid", + icon='MOD_SUBSURF', + ) + layout.operator( + "pov.addheightfield", text="Height Field", icon="RNDCURVE" + ) + layout.operator( + "pov.addspheresweep", text="Sphere Sweep", icon='FORCE_CURVE' + ) layout.separator() - layout.operator("pov.addblobsphere", text="Blob Sphere",icon = 'META_DATA') + layout.operator( + "pov.addblobsphere", text="Blob Sphere", icon='META_DATA' + ) layout.separator() layout.label(text="Isosurfaces") - layout.operator("pov.addisosurfacebox", text="Isosurface Box",icon="META_CUBE") - layout.operator("pov.addisosurfacesphere", text="Isosurface Sphere",icon="META_BALL") - layout.operator("pov.addsupertorus", text="Supertorus",icon="SURFACE_NTORUS") + layout.operator( + "pov.addisosurfacebox", text="Isosurface Box", icon="META_CUBE" + ) + layout.operator( + "pov.addisosurfacesphere", + text="Isosurface Sphere", + icon="META_BALL", + ) + layout.operator( + "pov.addsupertorus", text="Supertorus", icon="SURFACE_NTORUS" + ) layout.separator() - layout.label(text = "Macro based") - layout.operator("pov.addpolygontocircle", text="Polygon To Circle Blending",icon="MOD_CAST") - layout.operator("pov.addloft", text="Loft",icon="SURFACE_NSURFACE") + layout.label(text="Macro based") + layout.operator( + "pov.addpolygontocircle", + text="Polygon To Circle Blending", + icon="MOD_CAST", + ) + layout.operator("pov.addloft", text="Loft", icon="SURFACE_NSURFACE") layout.separator() # Warning if the Add Advanced Objects addon containing # Add mesh extra objects is not enabled if not check_add_mesh_extra_objects(): - #col = box.column() - layout.label(text="Please enable Add Mesh: Extra Objects addon", icon="INFO") - #layout.separator() - layout.operator("preferences.addon_show", - text="Go to Add Mesh: Extra Objects addon", - icon="PREFERENCES").module = "add_mesh_extra_objects" - - #layout.separator() + # col = box.column() + layout.label( + text="Please enable Add Mesh: Extra Objects addon", icon="INFO" + ) + # layout.separator() + layout.operator( + "preferences.addon_show", + text="Go to Add Mesh: Extra Objects addon", + icon="PREFERENCES", + ).module = "add_mesh_extra_objects" + + # layout.separator() return else: - layout.operator("pov.addparametric", text="Parametric",icon = 'SCRIPTPLUGINS') + layout.operator( + "pov.addparametric", text="Parametric", icon='SCRIPTPLUGINS' + ) + class VIEW_MT_POV_import(bpy.types.Menu): """Use this class for the import menu.""" @@ -3149,69 +3805,77 @@ class VIEW_MT_POV_import(bpy.types.Menu): bl_idname = "POVRAY_MT_import_tools" bl_label = "Import" - def draw(self,context): + def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("import_scene.pov",icon="FORCE_LENNARDJONES") + layout.operator("import_scene.pov", icon="FORCE_LENNARDJONES") + def menu_func_add(self, context): engine = context.scene.render.engine if engine == 'POVRAY_RENDER': self.layout.menu("VIEW_MT_POV_primitives_add", icon="PLUGIN") + def menu_func_import(self, context): engine = context.scene.render.engine if engine == 'POVRAY_RENDER': - self.layout.operator("import_scene.pov",icon="FORCE_LENNARDJONES") + self.layout.operator("import_scene.pov", icon="FORCE_LENNARDJONES") ##############Nodes # def find_node_input(node, name): - # for input in node.inputs: - # if input.name == name: - # return input +# for input in node.inputs: +# if input.name == name: +# return input # def panel_node_draw(layout, id_data, output_type, input_name): - # if not id_data.use_nodes: - # #layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') - # #layout.operator("pov.use_shading_nodes", icon='NODETREE') - # layout.operator("WM_OT_context_toggle", icon='NODETREE').data_path = \ - # "material.pov.material_use_nodes" - # return False +# if not id_data.use_nodes: +# #layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') +# #layout.operator("pov.use_shading_nodes", icon='NODETREE') +# layout.operator("WM_OT_context_toggle", icon='NODETREE').data_path = \ +# "material.pov.material_use_nodes" +# return False + +# ntree = id_data.node_tree - # ntree = id_data.node_tree +# node = find_node(id_data, output_type) +# if not node: +# layout.label(text="No output node") +# else: +# input = find_node_input(node, input_name) +# layout.template_node_view(ntree, node, input) - # node = find_node(id_data, output_type) - # if not node: - # layout.label(text="No output node") - # else: - # input = find_node_input(node, input_name) - # layout.template_node_view(ntree, node, input) +# return True - # return True class NODE_MT_POV_map_create(bpy.types.Menu): """Create maps""" + bl_idname = "POVRAY_MT_node_map_create" bl_label = "Create map" - def draw(self,context): + def draw(self, context): layout = self.layout layout.operator("node.map_create") + def menu_func_nodes(self, context): ob = context.object - if hasattr(ob,'active_material'): - mat=context.object.active_material + if hasattr(ob, 'active_material'): + mat = context.object.active_material if mat and context.space_data.tree_type == 'ObjectNodeTree': - self.layout.prop(mat.pov,"material_use_nodes") + self.layout.prop(mat.pov, "material_use_nodes") self.layout.menu(NODE_MT_POV_map_create.bl_idname) self.layout.operator("wm.updatepreviewkey") - if hasattr(mat,'active_texture') and context.scene.render.engine == 'POVRAY_RENDER': - tex=mat.active_texture + if ( + hasattr(mat, 'active_texture') + and context.scene.render.engine == 'POVRAY_RENDER' + ): + tex = mat.active_texture if tex and context.space_data.tree_type == 'TextureNodeTree': - self.layout.prop(tex.pov,"texture_use_nodes") + self.layout.prop(tex.pov, "texture_use_nodes") ############################################################################### @@ -3224,10 +3888,10 @@ class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel): COMPAT_ENGINES = {'POVRAY_RENDER'} bl_parent_id = "DATA_PT_camera_dof_aperture" bl_options = {'HIDE_HEADER'} - #def draw_header(self, context): - #cam = context.camera + # def draw_header(self, context): + # cam = context.camera - #self.layout.prop(cam.pov, "dof_enable", text="") + # self.layout.prop(cam.pov, "dof_enable", text="") def draw(self, context): layout = self.layout @@ -3235,13 +3899,22 @@ class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel): cam = context.camera layout.active = cam.dof.use_dof - layout.use_property_split = True # Active single-column layout - - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + layout.use_property_split = True # Active single-column layout + + flow = layout.grid_flow( + row_major=True, + columns=0, + even_columns=True, + even_rows=False, + align=False, + ) col = flow.column() col.label(text="F-Stop value will export as") - col.label(text="POV aperture : " + "%.3f" % (1/cam.dof.aperture_fstop*1000)) + col.label( + text="POV aperture : " + + "%.3f" % (1 / cam.dof.aperture_fstop * 1000) + ) col = flow.column() col.prop(cam.pov, "dof_samples_min") @@ -3250,7 +3923,6 @@ class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel): col.prop(cam.pov, "dof_confidence") - class CAMERA_PT_POV_cam_nor(CameraDataButtonsPanel, Panel): """Use this class for camera normal perturbation buttons.""" @@ -3269,10 +3941,10 @@ class CAMERA_PT_POV_cam_nor(CameraDataButtonsPanel, Panel): layout.active = cam.pov.normal_enable - layout.prop(cam.pov,"normal_patterns") - layout.prop(cam.pov,"cam_normal") - layout.prop(cam.pov,"turbulence") - layout.prop(cam.pov,"scale") + layout.prop(cam.pov, "normal_patterns") + layout.prop(cam.pov, "cam_normal") + layout.prop(cam.pov, "turbulence") + layout.prop(cam.pov, "scale") class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel): @@ -3290,17 +3962,19 @@ class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel): col.label(text="Replace properties with:") col.prop(cam.pov, "replacement_text", text="") + ############################################################################### # Text Povray Settings ############################################################################### + class TEXT_OT_POV_insert(Operator): """Use this class to create blender text editor operator to insert pov snippets like other pov IDEs.""" bl_idname = "text.povray_insert" bl_label = "Insert" - filepath : bpy.props.StringProperty(name="Filepath", subtype='FILE_PATH') + filepath: bpy.props.StringProperty(name="Filepath", subtype='FILE_PATH') @classmethod def poll(cls, context): @@ -3317,8 +3991,10 @@ class TEXT_OT_POV_insert(Operator): file.close() return {'FINISHED'} + def validinsert(ext): - return ext in {".txt",".inc",".pov"} + return ext in {".txt", ".inc", ".pov"} + class TEXT_MT_POV_insert(bpy.types.Menu): """Use this class to create a menu launcher in text editor for the TEXT_OT_POV_insert operator .""" @@ -3328,19 +4004,23 @@ class TEXT_MT_POV_insert(bpy.types.Menu): def draw(self, context): pov_documents = locate_docpath() - prop = self.layout.operator("wm.path_open", text="Open folder", icon='FILE_FOLDER') + prop = self.layout.operator( + "wm.path_open", text="Open folder", icon='FILE_FOLDER' + ) prop.filepath = pov_documents self.layout.separator() - list=[] - for root,dirs,files in os.walk(pov_documents): + list = [] + for root, dirs, files in os.walk(pov_documents): list.append(root) print(list) - self.path_menu(list, - "text.povray_insert", - #{"internal": True}, - filter_ext= validinsert - ) + self.path_menu( + list, + "text.povray_insert", + # {"internal": True}, + filter_ext=validinsert, + ) + class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel): """Use this class to create a panel in text editor for the user to decide if he renders text only or adds to 3d scene.""" @@ -3354,42 +4034,45 @@ class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel): text = context.space_data.text pov_documents = locate_docpath() - if not pov_documents : + if not pov_documents: layout.label(text="Please configure ", icon="INFO") layout.label(text="default pov include path ") layout.label(text="in addon preferences") - #layout.separator() - layout.operator("preferences.addon_show", - text="Go to Render: Persistence of Vision addon", - icon="PREFERENCES").module = "render_povray" - - #layout.separator() + # layout.separator() + layout.operator( + "preferences.addon_show", + text="Go to Render: Persistence of Vision addon", + icon="PREFERENCES", + ).module = "render_povray" + + # layout.separator() else: - #print(pov_documents) + # print(pov_documents) layout.menu(TEXT_MT_POV_insert.bl_idname) if text: box = layout.box() box.label(text='Source to render:', icon='RENDER_STILL') row = box.row() - row.prop(text.pov, "custom_code",expand = True) + row.prop(text.pov, "custom_code", expand=True) if text.pov.custom_code in {'3dview'}: box.operator("render.render", icon='OUTLINER_DATA_POSE') if text.pov.custom_code in {'text'}: rtext = bpy.context.space_data.text box.operator("text.run", icon='POSE_DATA') - #layout.prop(text.pov, "custom_code") + # layout.prop(text.pov, "custom_code") elif text.pov.custom_code in {'both'}: box.operator("render.render", icon='POSE_HLT') layout.label(text="Please specify declared", icon="INFO") layout.label(text="items in properties ") - #layout.label(text="") + # layout.label(text="") layout.label(text="replacement fields") ############################################### # Text editor templates from header menu + class TEXT_MT_POV_templates(bpy.types.Menu): """Use this class to create a menu for the same pov templates scenes as other pov IDEs.""" @@ -3398,34 +4081,35 @@ class TEXT_MT_POV_templates(bpy.types.Menu): # We list templates on file evaluation, we can assume they are static data, # and better avoid running this on every draw call. import os + template_paths = [os.path.join(os.path.dirname(__file__), "templates_pov")] def draw(self, context): self.path_menu( - self.template_paths, - "text.open", - props_default={"internal": True}, + self.template_paths, "text.open", props_default={"internal": True} ) + def menu_func_templates(self, context): # Do not depend on POV being active renderer here... self.layout.menu("TEXT_MT_POV_templates") + classes = ( WORLD_PT_POV_world, WORLD_MT_POV_presets, WORLD_OT_POV_add_preset, WORLD_TEXTURE_SLOTS_UL_List, WORLD_PT_POV_mist, - #RenderButtonsPanel, - #ModifierButtonsPanel, - #MaterialButtonsPanel, - #TextureButtonsPanel, - #ObjectButtonsPanel, - #CameraDataButtonsPanel, - #WorldButtonsPanel, - #TextButtonsPanel, - #PovDataButtonsPanel, + # RenderButtonsPanel, + # ModifierButtonsPanel, + # MaterialButtonsPanel, + # TextureButtonsPanel, + # ObjectButtonsPanel, + # CameraDataButtonsPanel, + # WorldButtonsPanel, + # TextButtonsPanel, + # PovDataButtonsPanel, DATA_PT_POV_normals, DATA_PT_POV_texture_space, DATA_PT_POV_vertex_groups, @@ -3433,7 +4117,7 @@ classes = ( DATA_PT_POV_uv_texture, DATA_PT_POV_vertex_colors, DATA_PT_POV_customdata, - #PovLampButtonsPanel, + # PovLampButtonsPanel, LIGHT_PT_POV_preview, LIGHT_PT_POV_light, LIGHT_MT_POV_presets, @@ -3457,7 +4141,7 @@ classes = ( MATERIAL_PT_POV_mirror, MATERIAL_PT_POV_transp, MATERIAL_PT_POV_reflection, - #MATERIAL_PT_POV_interior, + # MATERIAL_PT_POV_interior, MATERIAL_PT_POV_fade_color, MATERIAL_PT_POV_caustics, MATERIAL_PT_POV_replacement_text, @@ -3488,17 +4172,17 @@ classes = ( TEXT_PT_POV_custom_code, TEXT_MT_POV_templates, # TEXTURE_PT_context, - #TEXTURE_PT_POV_povray_texture_slots, + # TEXTURE_PT_POV_povray_texture_slots, TEXTURE_UL_POV_texture_slots, MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist, MATERIAL_OT_POV_texture_slot_add, MATERIAL_OT_POV_texture_slot_remove, - TEXTURE_PT_POV_influence + TEXTURE_PT_POV_influence, ) def register(): - #from bpy.utils import register_class + # from bpy.utils import register_class for cls in classes: register_class(cls) @@ -3508,19 +4192,20 @@ def register(): bpy.types.TEXT_MT_templates.append(menu_func_templates) bpy.types.RENDER_PT_POV_radiosity.prepend(rad_panel_func) bpy.types.LIGHT_PT_POV_light.prepend(light_panel_func) - #bpy.types.WORLD_PT_POV_world.prepend(world_panel_func) + # bpy.types.WORLD_PT_POV_world.prepend(world_panel_func) # was used for parametric objects but made the other addon unreachable on # unregister for other tools to use created a user action call instead - #addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True) + # addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True) + + # bpy.types.TEXTURE_PT_context_texture.prepend(TEXTURE_PT_POV_type) - #bpy.types.TEXTURE_PT_context_texture.prepend(TEXTURE_PT_POV_type) def unregister(): - #from bpy.utils import unregister_class + # from bpy.utils import unregister_class - #bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_POV_type) - #addon_utils.disable("add_mesh_extra_objects", default_set=False) - #bpy.types.WORLD_PT_POV_world.remove(world_panel_func) + # bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_POV_type) + # addon_utils.disable("add_mesh_extra_objects", default_set=False) + # bpy.types.WORLD_PT_POV_world.remove(world_panel_func) bpy.types.LIGHT_PT_POV_light.remove(light_panel_func) bpy.types.RENDER_PT_POV_radiosity.remove(rad_panel_func) bpy.types.TEXT_MT_templates.remove(menu_func_templates) diff --git a/render_povray/update_files.py b/render_povray/update_files.py index 8b89c1f2abbdf5a49f1ff55c2a87f8dc15f0f93d..416e40d3732f7b889fc993d565f6b8227c9e0889 100644 --- a/render_povray/update_files.py +++ b/render_povray/update_files.py @@ -17,6 +17,7 @@ # ##### 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. @@ -24,13 +25,13 @@ This file needs an update.""" import bpy from bpy.props import ( - StringProperty, - BoolProperty, - IntProperty, - FloatProperty, - FloatVectorProperty, - EnumProperty, - ) + StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + EnumProperty, +) def update2_0_0_9(): @@ -41,45 +42,106 @@ def update2_0_0_9(): # XXX We could also store the new name, but as it is just the same without leading pov_ ... # Get default values of pov scene props. old_sce_props = {} - for k in ["pov_tempfiles_enable", "pov_deletefiles_enable", "pov_scene_name", "pov_scene_path", - "pov_renderimage_path", "pov_list_lf_enable", "pov_radio_enable", - "pov_radio_display_advanced", "pov_media_enable", "pov_media_samples", "pov_media_color", - "pov_baking_enable", "pov_indentation_character", "pov_indentation_spaces", - "pov_comments_enable", "pov_command_line_switches", "pov_antialias_enable", - "pov_antialias_method", "pov_antialias_depth", "pov_antialias_threshold", - "pov_jitter_enable", "pov_jitter_amount", "pov_antialias_gamma", "pov_max_trace_level", - "pov_photon_spacing", "pov_photon_max_trace_level", "pov_photon_adc_bailout", - "pov_photon_gather_min", "pov_photon_gather_max", "pov_radio_adc_bailout", - "pov_radio_always_sample", "pov_radio_brightness", "pov_radio_count", - "pov_radio_error_bound", "pov_radio_gray_threshold", "pov_radio_low_error_factor", - "pov_radio_media", "pov_radio_minimum_reuse", "pov_radio_nearest_count", - "pov_radio_normal", "pov_radio_recursion_limit", "pov_radio_pretrace_start", - "pov_radio_pretrace_end"]: + for k in [ + "pov_tempfiles_enable", + "pov_deletefiles_enable", + "pov_scene_name", + "pov_scene_path", + "pov_renderimage_path", + "pov_list_lf_enable", + "pov_radio_enable", + "pov_radio_display_advanced", + "pov_media_enable", + "pov_media_samples", + "pov_media_color", + "pov_baking_enable", + "pov_indentation_character", + "pov_indentation_spaces", + "pov_comments_enable", + "pov_command_line_switches", + "pov_antialias_enable", + "pov_antialias_method", + "pov_antialias_depth", + "pov_antialias_threshold", + "pov_jitter_enable", + "pov_jitter_amount", + "pov_antialias_gamma", + "pov_max_trace_level", + "pov_photon_spacing", + "pov_photon_max_trace_level", + "pov_photon_adc_bailout", + "pov_photon_gather_min", + "pov_photon_gather_max", + "pov_radio_adc_bailout", + "pov_radio_always_sample", + "pov_radio_brightness", + "pov_radio_count", + "pov_radio_error_bound", + "pov_radio_gray_threshold", + "pov_radio_low_error_factor", + "pov_radio_media", + "pov_radio_minimum_reuse", + "pov_radio_nearest_count", + "pov_radio_normal", + "pov_radio_recursion_limit", + "pov_radio_pretrace_start", + "pov_radio_pretrace_end", + ]: old_sce_props[k] = getattr(bpy.types.Scene, k)[1].get('default', None) # Get default values of pov material props. old_mat_props = {} - for k in ["pov_irid_enable", "pov_mirror_use_IOR", "pov_mirror_metallic", "pov_conserve_energy", - "pov_irid_amount", "pov_irid_thickness", "pov_irid_turbulence", "pov_interior_fade_color", - "pov_caustics_enable", "pov_fake_caustics", "pov_fake_caustics_power", - "pov_photons_refraction", "pov_photons_dispersion", "pov_photons_reflection", - "pov_refraction_type", "pov_replacement_text"]: - old_mat_props[k] = getattr(bpy.types.Material, k)[1].get('default', None) + for k in [ + "pov_irid_enable", + "pov_mirror_use_IOR", + "pov_mirror_metallic", + "pov_conserve_energy", + "pov_irid_amount", + "pov_irid_thickness", + "pov_irid_turbulence", + "pov_interior_fade_color", + "pov_caustics_enable", + "pov_fake_caustics", + "pov_fake_caustics_power", + "pov_photons_refraction", + "pov_photons_dispersion", + "pov_photons_reflection", + "pov_refraction_type", + "pov_replacement_text", + ]: + old_mat_props[k] = getattr(bpy.types.Material, k)[1].get( + 'default', None + ) # Get default values of pov texture props. old_tex_props = {} - for k in ["pov_tex_gamma_enable", "pov_tex_gamma_value", "pov_replacement_text"]: + for k in [ + "pov_tex_gamma_enable", + "pov_tex_gamma_value", + "pov_replacement_text", + ]: old_tex_props[k] = getattr(bpy.types.Texture, k)[1].get('default', None) # Get default values of pov object props. old_obj_props = {} - for k in ["pov_importance_value", "pov_collect_photons", "pov_replacement_text"]: + for k in [ + "pov_importance_value", + "pov_collect_photons", + "pov_replacement_text", + ]: old_obj_props[k] = getattr(bpy.types.Object, k)[1].get('default', None) # Get default values of pov camera props. old_cam_props = {} - for k in ["pov_dof_enable", "pov_dof_aperture", "pov_dof_samples_min", "pov_dof_samples_max", - "pov_dof_variance", "pov_dof_confidence", "pov_replacement_text"]: + for k in [ + "pov_dof_enable", + "pov_dof_aperture", + "pov_dof_samples_min", + "pov_dof_samples_max", + "pov_dof_variance", + "pov_dof_confidence", + "pov_replacement_text", + ]: old_cam_props[k] = getattr(bpy.types.Camera, k)[1].get('default', None) # Get default values of pov text props. @@ -128,6 +190,7 @@ def update2_0_0_9(): class RenderCopySettings(bpy.types.Operator): """Update old POV properties to new ones""" + bl_idname = "scene.pov_update_properties" bl_label = "PovRay render: Update to script v0.0.9" bl_option = {'REGISTER'} @@ -152,372 +215,598 @@ def register(): # File Options Scene.pov_tempfiles_enable = BoolProperty( - name="Enable Tempfiles", - description="Enable the OS-Tempfiles. Otherwise set the path where to save the files", - default=True) + name="Enable Tempfiles", + description="Enable the OS-Tempfiles. Otherwise set the path where to save the files", + default=True, + ) Scene.pov_deletefiles_enable = BoolProperty( - name="Delete files", - description="Delete files after rendering. Doesn't work with the image", - default=True) + name="Delete files", + description="Delete files after rendering. Doesn't work with the image", + default=True, + ) Scene.pov_scene_name = StringProperty( - name="Scene Name", - description="Name of POV-Ray scene to create. Empty name will use the name of the blend file", - default="", maxlen=1024) + name="Scene Name", + description="Name of POV-Ray scene to create. Empty name will use the name of the blend file", + default="", + maxlen=1024, + ) Scene.pov_scene_path = StringProperty( - name="Export scene path", - # description="Path to directory where the exported scene (POV and INI) is created", # Bug in POV-Ray RC3 - description="Path to directory where the files are created", - default="", maxlen=1024, subtype="DIR_PATH") + name="Export scene path", + # description="Path to directory where the exported scene (POV and INI) is created", # Bug in POV-Ray RC3 + description="Path to directory where the files are created", + default="", + maxlen=1024, + subtype="DIR_PATH", + ) Scene.pov_renderimage_path = StringProperty( - name="Rendered image path", - description="Full path to directory where the rendered image is saved", - default="", maxlen=1024, subtype="DIR_PATH") + name="Rendered image path", + description="Full path to directory where the rendered image is saved", + default="", + maxlen=1024, + subtype="DIR_PATH", + ) Scene.pov_list_lf_enable = BoolProperty( - name="LF in lists", - description="Enable line breaks in lists (vectors and indices). Disabled: lists are exported in one line", - default=True) + name="LF in lists", + description="Enable line breaks in lists (vectors and indices). Disabled: lists are exported in one line", + default=True, + ) # Not a real pov option, just to know if we should write Scene.pov_radio_enable = BoolProperty( - name="Enable Radiosity", - description="Enable POV-Rays radiosity calculation", - default=False) + name="Enable Radiosity", + description="Enable POV-Rays radiosity calculation", + default=False, + ) Scene.pov_radio_display_advanced = BoolProperty( - name="Advanced Options", - description="Show advanced options", - default=False) + name="Advanced Options", + description="Show advanced options", + default=False, + ) Scene.pov_media_enable = BoolProperty( - name="Enable Media", - description="Enable POV-Rays atmospheric media", - default=False) + name="Enable Media", + description="Enable POV-Rays atmospheric media", + default=False, + ) Scene.pov_media_samples = IntProperty( - name="Samples", description="Number of samples taken from camera to first object encountered along ray path for media calculation", - min=1, max=100, default=35) + name="Samples", + description="Number of samples taken from camera to first object encountered along ray path for media calculation", + min=1, + max=100, + default=35, + ) Scene.pov_media_color = FloatVectorProperty( - name="Media Color", - description="The atmospheric media color", - subtype='COLOR', - precision=4, - step=0.01, - min=0, - soft_max=1, - default=(0.001, 0.001, 0.001), - options={'ANIMATABLE'}) + name="Media Color", + description="The atmospheric media color", + subtype='COLOR', + precision=4, + step=0.01, + min=0, + soft_max=1, + default=(0.001, 0.001, 0.001), + options={'ANIMATABLE'}, + ) Scene.pov_baking_enable = BoolProperty( - name="Enable Baking", - description="Enable POV-Rays texture baking", - default=False) + name="Enable Baking", + description="Enable POV-Rays texture baking", + default=False, + ) Scene.pov_indentation_character = EnumProperty( - name="Indentation", - description="Select the indentation type", - items=(("0", "None", "No indentation"), - ("1", "Tabs", "Indentation with tabs"), - ("2", "Spaces", "Indentation with spaces")), - default="2") + name="Indentation", + description="Select the indentation type", + items=( + ("0", "None", "No indentation"), + ("1", "Tabs", "Indentation with tabs"), + ("2", "Spaces", "Indentation with spaces"), + ), + default="2", + ) Scene.pov_indentation_spaces = IntProperty( - name="Quantity of spaces", - description="The number of spaces for indentation", - min=1, max=10, default=4) + name="Quantity of spaces", + description="The number of spaces for indentation", + min=1, + max=10, + default=4, + ) Scene.pov_comments_enable = BoolProperty( - name="Enable Comments", - description="Add comments to pov file", - default=True) + name="Enable Comments", + description="Add comments to pov file", + default=True, + ) # Real pov options - Scene.pov_command_line_switches = StringProperty(name="Command Line Switches", - description="Command line switches consist of a + (plus) or - (minus) sign, followed by one or more alphabetic characters and possibly a numeric value", - default="", maxlen=500) + Scene.pov_command_line_switches = StringProperty( + name="Command Line Switches", + description="Command line switches consist of a + (plus) or - (minus) sign, followed by one or more alphabetic characters and possibly a numeric value", + default="", + maxlen=500, + ) Scene.pov_antialias_enable = BoolProperty( - name="Anti-Alias", description="Enable Anti-Aliasing", - default=True) + name="Anti-Alias", description="Enable Anti-Aliasing", default=True + ) Scene.pov_antialias_method = EnumProperty( - name="Method", - description="AA-sampling method. Type 1 is an adaptive, non-recursive, super-sampling method. Type 2 is an adaptive and recursive super-sampling method", - items=(("0", "non-recursive AA", "Type 1 Sampling in POV-Ray"), - ("1", "recursive AA", "Type 2 Sampling in POV-Ray")), - default="1") + name="Method", + description="AA-sampling method. Type 1 is an adaptive, non-recursive, super-sampling method. Type 2 is an adaptive and recursive super-sampling method", + items=( + ("0", "non-recursive AA", "Type 1 Sampling in POV-Ray"), + ("1", "recursive AA", "Type 2 Sampling in POV-Ray"), + ), + default="1", + ) Scene.pov_antialias_depth = IntProperty( - name="Antialias Depth", description="Depth of pixel for sampling", - min=1, max=9, default=3) + name="Antialias Depth", + description="Depth of pixel for sampling", + min=1, + max=9, + default=3, + ) Scene.pov_antialias_threshold = FloatProperty( - name="Antialias Threshold", description="Tolerance for sub-pixels", - min=0.0, max=1.0, soft_min=0.05, soft_max=0.5, default=0.1) + name="Antialias Threshold", + description="Tolerance for sub-pixels", + min=0.0, + max=1.0, + soft_min=0.05, + soft_max=0.5, + default=0.1, + ) Scene.pov_jitter_enable = BoolProperty( - name="Jitter", description="Enable Jittering. Adds noise into the sampling process (it should be avoided to use jitter in animation)", - default=True) + name="Jitter", + description="Enable Jittering. Adds noise into the sampling process (it should be avoided to use jitter in animation)", + default=True, + ) Scene.pov_jitter_amount = FloatProperty( - name="Jitter Amount", description="Amount of jittering", - min=0.0, max=1.0, soft_min=0.01, soft_max=1.0, default=1.0) + name="Jitter Amount", + description="Amount of jittering", + min=0.0, + max=1.0, + soft_min=0.01, + soft_max=1.0, + default=1.0, + ) Scene.pov_antialias_gamma = FloatProperty( - name="Antialias Gamma", description="POV-Ray compares gamma-adjusted values for super sampling. Antialias Gamma sets the Gamma before comparison", - min=0.0, max=5.0, soft_min=0.01, soft_max=2.5, default=2.5) + name="Antialias Gamma", + description="POV-Ray compares gamma-adjusted values for super sampling. Antialias Gamma sets the Gamma before comparison", + min=0.0, + max=5.0, + soft_min=0.01, + soft_max=2.5, + default=2.5, + ) Scene.pov_max_trace_level = IntProperty( - name="Max Trace Level", description="Number of reflections/refractions allowed on ray path", - min=1, max=256, default=5) + name="Max Trace Level", + description="Number of reflections/refractions allowed on ray path", + min=1, + max=256, + default=5, + ) Scene.pov_photon_spacing = FloatProperty( - name="Spacing", description="Average distance between photons on surfaces. half this get four times as many surface photons", - min=0.001, max=1.000, soft_min=0.001, soft_max=1.000, default=0.005, precision=3) + name="Spacing", + description="Average distance between photons on surfaces. half this get four times as many surface photons", + min=0.001, + max=1.000, + soft_min=0.001, + soft_max=1.000, + default=0.005, + precision=3, + ) Scene.pov_photon_max_trace_level = IntProperty( - name="Max Trace Level", description="Number of reflections/refractions allowed on ray path", - min=1, max=256, default=5) + name="Max Trace Level", + description="Number of reflections/refractions allowed on ray path", + min=1, + max=256, + default=5, + ) Scene.pov_photon_adc_bailout = FloatProperty( - name="ADC Bailout", description="The adc_bailout for photons. Use adc_bailout = 0.01 / brightest_ambient_object for good results", - min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default=0.1, precision=3) + name="ADC Bailout", + description="The adc_bailout for photons. Use adc_bailout = 0.01 / brightest_ambient_object for good results", + min=0.0, + max=1000.0, + soft_min=0.0, + soft_max=1.0, + default=0.1, + precision=3, + ) Scene.pov_photon_gather_min = IntProperty( - name="Gather Min", description="Minimum number of photons gathered for each point", - min=1, max=256, default=20) + name="Gather Min", + description="Minimum number of photons gathered for each point", + min=1, + max=256, + default=20, + ) Scene.pov_photon_gather_max = IntProperty( - name="Gather Max", description="Maximum number of photons gathered for each point", - min=1, max=256, default=100) + name="Gather Max", + description="Maximum number of photons gathered for each point", + min=1, + max=256, + default=100, + ) Scene.pov_radio_adc_bailout = FloatProperty( - name="ADC Bailout", description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results", - min=0.0, max=1000.0, soft_min=0.0, soft_max=1.0, default=0.01, precision=3) + name="ADC Bailout", + description="The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results", + min=0.0, + max=1000.0, + soft_min=0.0, + soft_max=1.0, + default=0.01, + precision=3, + ) Scene.pov_radio_always_sample = BoolProperty( - name="Always Sample", description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass", - default=True) + name="Always Sample", + description="Only use the data from the pretrace step and not gather any new samples during the final radiosity pass", + default=True, + ) Scene.pov_radio_brightness = FloatProperty( - name="Brightness", description="Amount objects are brightened before being returned upwards to the rest of the system", - min=0.0, max=1000.0, soft_min=0.0, soft_max=10.0, default=1.0) + name="Brightness", + description="Amount objects are brightened before being returned upwards to the rest of the system", + min=0.0, + max=1000.0, + soft_min=0.0, + soft_max=10.0, + default=1.0, + ) Scene.pov_radio_count = IntProperty( - name="Ray Count", description="Number of rays for each new radiosity value to be calculated (halton sequence over 1600)", - min=1, max=10000, soft_max=1600, default=35) + name="Ray Count", + description="Number of rays for each new radiosity value to be calculated (halton sequence over 1600)", + min=1, + max=10000, + soft_max=1600, + default=35, + ) Scene.pov_radio_error_bound = FloatProperty( - name="Error Bound", description="One of the two main speed/quality tuning values, lower values are more accurate", - min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1.8) + name="Error Bound", + description="One of the two main speed/quality tuning values, lower values are more accurate", + min=0.0, + max=1000.0, + soft_min=0.1, + soft_max=10.0, + default=1.8, + ) Scene.pov_radio_gray_threshold = FloatProperty( - name="Gray Threshold", description="One of the two main speed/quality tuning values, lower values are more accurate", - min=0.0, max=1.0, soft_min=0, soft_max=1, default=0.0) + name="Gray Threshold", + description="One of the two main speed/quality tuning values, lower values are more accurate", + min=0.0, + max=1.0, + soft_min=0, + soft_max=1, + default=0.0, + ) Scene.pov_radio_low_error_factor = FloatProperty( - name="Low Error Factor", description="Just enough samples is slightly blotchy. Low error changes error tolerance for less critical last refining pass", - min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, default=0.5) + name="Low Error Factor", + description="Just enough samples is slightly blotchy. Low error changes error tolerance for less critical last refining pass", + min=0.0, + max=1.0, + soft_min=0.0, + soft_max=1.0, + default=0.5, + ) # max_sample - not available yet Scene.pov_radio_media = BoolProperty( - name="Media", description="Radiosity estimation can be affected by media", - default=False) + name="Media", + description="Radiosity estimation can be affected by media", + default=False, + ) Scene.pov_radio_minimum_reuse = FloatProperty( - name="Minimum Reuse", description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors)", - min=0.0, max=1.0, soft_min=0.1, soft_max=0.1, default=0.015, precision=3) + name="Minimum Reuse", + description="Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors)", + min=0.0, + max=1.0, + soft_min=0.1, + soft_max=0.1, + default=0.015, + precision=3, + ) Scene.pov_radio_nearest_count = IntProperty( - name="Nearest Count", description="Number of old ambient values blended together to create a new interpolated value", - min=1, max=20, default=5) + name="Nearest Count", + description="Number of old ambient values blended together to create a new interpolated value", + min=1, + max=20, + default=5, + ) Scene.pov_radio_normal = BoolProperty( - name="Normals", description="Radiosity estimation can be affected by normals", - default=False) + name="Normals", + description="Radiosity estimation can be affected by normals", + default=False, + ) Scene.pov_radio_recursion_limit = IntProperty( - name="Recursion Limit", description="how many recursion levels are used to calculate the diffuse inter-reflection", - min=1, max=20, default=3) + name="Recursion Limit", + description="how many recursion levels are used to calculate the diffuse inter-reflection", + min=1, + max=20, + default=3, + ) Scene.pov_radio_pretrace_start = FloatProperty( - name="Pretrace Start", description="Fraction of the screen width which sets the size of the blocks in the mosaic preview first pass", - min=0.01, max=1.00, soft_min=0.02, soft_max=1.0, default=0.08) + name="Pretrace Start", + description="Fraction of the screen width which sets the size of the blocks in the mosaic preview first pass", + min=0.01, + max=1.00, + soft_min=0.02, + soft_max=1.0, + default=0.08, + ) Scene.pov_radio_pretrace_end = FloatProperty( - name="Pretrace End", description="Fraction of the screen width which sets the size of the blocks in the mosaic preview last pass", - min=0.001, max=1.00, soft_min=0.01, soft_max=1.00, default=0.04, precision=3) + name="Pretrace End", + description="Fraction of the screen width which sets the size of the blocks in the mosaic preview last pass", + min=0.001, + max=1.00, + soft_min=0.01, + soft_max=1.00, + default=0.04, + precision=3, + ) #############################MATERIAL###################################### Mat.pov_irid_enable = BoolProperty( - name="Enable Iridescence", - description="Newton's thin film interference (like an oil slick on a puddle of water or the rainbow hues of a soap bubble.)", - default=False) + name="Enable Iridescence", + description="Newton's thin film interference (like an oil slick on a puddle of water or the rainbow hues of a soap bubble.)", + default=False, + ) Mat.pov_mirror_use_IOR = BoolProperty( - name="Correct Reflection", - description="Use same IOR as raytrace transparency to calculate mirror reflections. More physically correct", - default=False) + name="Correct Reflection", + description="Use same IOR as raytrace transparency to calculate mirror reflections. More physically correct", + default=False, + ) Mat.pov_mirror_metallic = BoolProperty( - name="Metallic Reflection", - description="mirror reflections get colored as diffuse (for metallic materials)", - default=False) + name="Metallic Reflection", + description="mirror reflections get colored as diffuse (for metallic materials)", + default=False, + ) Mat.pov_conserve_energy = BoolProperty( - name="Conserve Energy", - description="Light transmitted is more correctly reduced by mirror reflections, also the sum of diffuse and translucency gets reduced below one ", - default=True) + name="Conserve Energy", + description="Light transmitted is more correctly reduced by mirror reflections, also the sum of diffuse and translucency gets reduced below one ", + default=True, + ) Mat.pov_irid_amount = FloatProperty( - name="amount", - description="Contribution of the iridescence effect to the overall surface color. As a rule of thumb keep to around 0.25 (25% contribution) or less, but experiment. If the surface is coming out too white, try lowering the diffuse and possibly the ambient values of the surface", - min=0.0, max=1.0, soft_min=0.01, soft_max=1.0, default=0.25) + name="amount", + description="Contribution of the iridescence effect to the overall surface color. As a rule of thumb keep to around 0.25 (25% contribution) or less, but experiment. If the surface is coming out too white, try lowering the diffuse and possibly the ambient values of the surface", + min=0.0, + max=1.0, + soft_min=0.01, + soft_max=1.0, + default=0.25, + ) Mat.pov_irid_thickness = FloatProperty( - name="thickness", - description="A very thin film will have a high frequency of color changes while a thick film will have large areas of color", - min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1) + name="thickness", + description="A very thin film will have a high frequency of color changes while a thick film will have large areas of color", + min=0.0, + max=1000.0, + soft_min=0.1, + soft_max=10.0, + default=1, + ) Mat.pov_irid_turbulence = FloatProperty( - name="turbulence", - description="This parameter varies the thickness", - min=0.0, max=10.0, soft_min=0.000, soft_max=1.0, default=0) + name="turbulence", + description="This parameter varies the thickness", + min=0.0, + max=10.0, + soft_min=0.000, + soft_max=1.0, + default=0, + ) Mat.pov_interior_fade_color = FloatVectorProperty( - name="Fade Color", - description="Color of filtered attenuation for transparent materials", - subtype='COLOR', - precision=4, - step=0.01, - min=0.0, - soft_max=1.0, - default=(0, 0, 0), - options={'ANIMATABLE'}) + name="Fade Color", + description="Color of filtered attenuation for transparent materials", + subtype='COLOR', + precision=4, + step=0.01, + min=0.0, + soft_max=1.0, + default=(0, 0, 0), + options={'ANIMATABLE'}, + ) Mat.pov_caustics_enable = BoolProperty( - name="Caustics", - description="use only fake refractive caustics (default) or photon based reflective/refractive caustics", - default=True) + name="Caustics", + description="use only fake refractive caustics (default) or photon based reflective/refractive caustics", + default=True, + ) Mat.pov_fake_caustics = BoolProperty( - name="Fake Caustics", - description="use only (Fast) fake refractive caustics", - default=True) + name="Fake Caustics", + description="use only (Fast) fake refractive caustics", + default=True, + ) Mat.pov_fake_caustics_power = FloatProperty( - name="Fake caustics power", - description="Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. Low, non-zero values give broad hot-spots while higher values give tighter, smaller simulated focal points", - min=0.00, max=10.0, soft_min=0.00, soft_max=1.10, default=0.1) + name="Fake caustics power", + description="Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. Low, non-zero values give broad hot-spots while higher values give tighter, smaller simulated focal points", + min=0.00, + max=10.0, + soft_min=0.00, + soft_max=1.10, + default=0.1, + ) Mat.pov_photons_refraction = BoolProperty( - name="Refractive Photon Caustics", - description="more physically correct", - default=False) + name="Refractive Photon Caustics", + description="more physically correct", + default=False, + ) Mat.pov_photons_dispersion = FloatProperty( - name="chromatic dispersion", - description="Light passing through will be separated according to wavelength. This ratio of refractive indices for violet to red controls how much the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1", - min=1.0000, max=10.000, soft_min=1.0000, soft_max=1.1000, precision=4, default=1.0000) + name="chromatic dispersion", + description="Light passing through will be separated according to wavelength. This ratio of refractive indices for violet to red controls how much the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1", + min=1.0000, + max=10.000, + soft_min=1.0000, + soft_max=1.1000, + precision=4, + default=1.0000, + ) Mat.pov_photons_reflection = BoolProperty( - name="Reflective Photon Caustics", - description="Use this to make your Sauron's ring ;-P", - default=False) + name="Reflective Photon Caustics", + description="Use this to make your Sauron's ring ;-P", + default=False, + ) Mat.pov_refraction_type = EnumProperty( - items=[("0", "None", "use only reflective caustics"), - ("1", "Fake Caustics", "use fake caustics"), - ("2", "Photons Caustics", "use photons for refractive caustics"), - ], - name="Refractive", - description="use fake caustics (fast) or true photons for refractive Caustics", - default="1") + items=[ + ("0", "None", "use only reflective caustics"), + ("1", "Fake Caustics", "use fake caustics"), + ("2", "Photons Caustics", "use photons for refractive caustics"), + ], + name="Refractive", + description="use fake caustics (fast) or true photons for refractive Caustics", + default="1", + ) ##################################CustomPOV Code############################ Mat.pov_replacement_text = StringProperty( - name="Declared name:", - description="Type the declared name in custom POV code or an external .inc it points at. texture {} expected", - default="") + name="Declared name:", + description="Type the declared name in custom POV code or an external .inc it points at. texture {} expected", + default="", + ) - #Only DUMMIES below for now: + # Only DUMMIES below for now: Tex.pov_replacement_text = StringProperty( - name="Declared name:", - description="Type the declared name in custom POV code or an external .inc it points at. pigment {} expected", - default="") + name="Declared name:", + description="Type the declared name in custom POV code or an external .inc it points at. pigment {} expected", + default="", + ) Obj.pov_replacement_text = StringProperty( - name="Declared name:", - description="Type the declared name in custom POV code or an external .inc it points at. Any POV shape expected e.g: isosurface {}", - default="") + name="Declared name:", + description="Type the declared name in custom POV code or an external .inc it points at. Any POV shape expected e.g: isosurface {}", + default="", + ) Cam.pov_replacement_text = StringProperty( - name="Texts in blend file", - description="Type the declared name in custom POV code or an external .inc it points at. camera {} expected", - default="") + name="Texts in blend file", + description="Type the declared name in custom POV code or an external .inc it points at. camera {} expected", + default="", + ) ##############################TEXTURE###################################### - #Custom texture gamma + # Custom texture gamma Tex.pov_tex_gamma_enable = BoolProperty( - name="Enable custom texture gamma", - description="Notify some custom gamma for which texture has been precorrected without the file format carrying it and only if it differs from your OS expected standard (see pov doc)", - default=False) + name="Enable custom texture gamma", + description="Notify some custom gamma for which texture has been precorrected without the file format carrying it and only if it differs from your OS expected standard (see pov doc)", + default=False, + ) Tex.pov_tex_gamma_value = FloatProperty( - name="Custom texture gamma", - description="value for which the file was issued e.g. a Raw photo is gamma 1.0", - min=0.45, max=5.00, soft_min=1.00, soft_max=2.50, default=1.00) + name="Custom texture gamma", + description="value for which the file was issued e.g. a Raw photo is gamma 1.0", + min=0.45, + max=5.00, + soft_min=1.00, + soft_max=2.50, + default=1.00, + ) #################################OBJECT#################################### - #Importance sampling + # Importance sampling Obj.pov_importance_value = FloatProperty( - name="Radiosity Importance", - description="Priority value relative to other objects for sampling radiosity rays. Increase to get more radiosity rays at comparatively small yet bright objects", - min=0.01, max=1.00, default=1.00) - - #Collect photons + name="Radiosity Importance", + description="Priority value relative to other objects for sampling radiosity rays. Increase to get more radiosity rays at comparatively small yet bright objects", + min=0.01, + max=1.00, + default=1.00, + ) + + # Collect photons Obj.pov_collect_photons = BoolProperty( - name="Receive Photon Caustics", - description="Enable object to collect photons from other objects caustics. Turn off for objects that don't really need to receive caustics (e.g. objects that generate caustics often don't need to show any on themselves) ", - default=True) + name="Receive Photon Caustics", + description="Enable object to collect photons from other objects caustics. Turn off for objects that don't really need to receive caustics (e.g. objects that generate caustics often don't need to show any on themselves) ", + default=True, + ) ##################################CAMERA################################### - #DOF Toggle + # DOF Toggle Cam.pov_dof_enable = BoolProperty( - name="Depth Of Field", - description="Enable POV-Ray Depth Of Field ", - default=True) + name="Depth Of Field", + description="Enable POV-Ray Depth Of Field ", + default=True, + ) - #Aperture (Intensity of the Blur) + # Aperture (Intensity of the Blur) Cam.pov_dof_aperture = FloatProperty( - name="Aperture", - description="Similar to a real camera's aperture effect over focal blur (though not in physical units and independent of focal length).Increase to get more blur", - min=0.01, max=1.00, default=0.25) - - #Aperture adaptive sampling + name="Aperture", + description="Similar to a real camera's aperture effect over focal blur (though not in physical units and independent of focal length).Increase to get more blur", + min=0.01, + max=1.00, + default=0.25, + ) + + # Aperture adaptive sampling Cam.pov_dof_samples_min = IntProperty( - name="Samples Min", - description="Minimum number of rays to use for each pixel", - min=1, max=128, default=96) + name="Samples Min", + description="Minimum number of rays to use for each pixel", + min=1, + max=128, + default=96, + ) Cam.pov_dof_samples_max = IntProperty( - name="Samples Max", - description="Maximum number of rays to use for each pixel", - min=1, max=128, default=128) + name="Samples Max", + description="Maximum number of rays to use for each pixel", + min=1, + max=128, + default=128, + ) Cam.pov_dof_variance = IntProperty( - name="Variance", - description="Minimum threshold (fractional value) for adaptive DOF sampling (up increases quality and render time). The value for the variance should be in the range of the smallest displayable color difference", - min=1, max=100000, soft_max=10000, default=256) + name="Variance", + description="Minimum threshold (fractional value) for adaptive DOF sampling (up increases quality and render time). The value for the variance should be in the range of the smallest displayable color difference", + min=1, + max=100000, + soft_max=10000, + default=256, + ) Cam.pov_dof_confidence = FloatProperty( - name="Confidence", - description="Probability to reach the real color value. Larger confidence values will lead to more samples, slower traces and better images", - min=0.01, max=0.99, default=0.90) + name="Confidence", + description="Probability to reach the real color value. Larger confidence values will lead to more samples, slower traces and better images", + min=0.01, + max=0.99, + default=0.90, + ) ###################################TEXT#################################### Text.pov_custom_code = BoolProperty( - name="Custom Code", - description="Add this text at the top of the exported POV-Ray file", - default=False) + name="Custom Code", + description="Add this text at the top of the exported POV-Ray file", + default=False, + ) def unregister():