# ##### 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 ##### # ############ To get POV-Ray specific objects In and Out of Blender ########### import bpy import os.path from bpy_extras.io_utils import ImportHelper from bpy_extras import object_utils 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, ) #import collections def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True): if mesh is None: mesh = bpy.data.meshes.new(name) mesh.from_pydata(verts, edges, faces) mesh.update() mesh.validate(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)) mesh.polygons.foreach_set("hide", [True] * len(mesh.polygons)) return mesh class POVRAY_OT_lathe_add(bpy.types.Operator): bl_idname = "pov.addlathe" bl_label = "Lathe" bl_options = {'REGISTER','UNDO'} bl_description = "adds lathe" def execute(self, context): layers=[False]*20 layers[0]=True bpy.ops.curve.primitive_bezier_curve_add( location=context.scene.cursor_location, rotation=(0, 0, 0), layers=layers, ) ob = context.scene.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' self.report({'INFO'}, "This native POV-Ray primitive") ob.pov.curveshape = "lathe" bpy.ops.object.modifier_add(type='SCREW') mod = ob.modifiers[-1] mod.axis = 'Y' mod.show_render = False return {'FINISHED'} def pov_superellipsoid_define(context, op, ob): if op: mesh = None u = op.se_u v = op.se_v n1 = op.se_n1 n2 = op.se_n2 edit = op.se_edit se_param1 = n2 # op.se_param1 se_param2 = n1 # op.se_param2 else: assert(ob) mesh = ob.data u = ob.pov.se_u v = ob.pov.se_v n1 = ob.pov.se_n1 n2 = ob.pov.se_n2 edit = ob.pov.se_edit se_param1 = ob.pov.se_param1 se_param2 = ob.pov.se_param2 verts = [] r=1 stepSegment=360/v*pi/180 stepRing=pi/u angSegment=0 angRing=-pi/2 step=0 for ring in range(0,u-1): angRing += stepRing for segment in range(0,v): step += 1 angSegment += stepSegment x = r*(abs(cos(angRing))**n1)*(abs(cos(angSegment))**n2) if (cos(angRing) < 0 and cos(angSegment) > 0) or \ (cos(angRing) > 0 and cos(angSegment) < 0): x = -x y = r*(abs(cos(angRing))**n1)*(abs(sin(angSegment))**n2) if (cos(angRing) < 0 and sin(angSegment) > 0) or \ (cos(angRing) > 0 and sin(angSegment) < 0): y = -y z = r*(abs(sin(angRing))**n1) if sin(angRing) < 0: z = -z x = round(x,4) y = round(y,4) z = round(z,4) verts.append((x,y,z)) if edit == 'TRIANGLES': verts.append((0,0,1)) verts.append((0,0,-1)) faces = [] for i in range(0,u-2): m=i*v for p in range(0,v): if p < v-1: face=(m+p,1+m+p,v+1+m+p,v+m+p) if p == v-1: face=(m+p,m,v+m,v+m+p) faces.append(face) if edit == 'TRIANGLES': indexUp=len(verts)-2 indexDown=len(verts)-1 indexStartDown=len(verts)-2-v for i in range(0,v): if i < v-1: face=(indexDown,i,i+1) faces.append(face) if i == v-1: face=(indexDown,i,0) faces.append(face) for i in range(0,v): if i < v-1: face=(indexUp,i+indexStartDown,i+indexStartDown+1) faces.append(face) if i == v-1: face=(indexUp,i+indexStartDown,indexStartDown) faces.append(face) if edit == 'NGONS': face=[] for i in range(0,v): face.append(i) faces.append(face) face=[] indexUp=len(verts)-1 for i in range(0,v): face.append(indexUp-i) faces.append(face) mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid") if not ob: ob_base = object_utils.object_data_add(context, mesh, operator=None) ob = ob_base.object #engine = context.scene.render.engine what for? ob = context.object ob.name = ob.data.name = "PovSuperellipsoid" ob.pov.object_as = 'SUPERELLIPSOID' ob.pov.se_param1 = n2 ob.pov.se_param2 = n1 ob.pov.se_u = u ob.pov.se_v = v ob.pov.se_n1 = n1 ob.pov.se_n2 = n2 ob.pov.se_edit = edit bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_superellipsoid_add(bpy.types.Operator): bl_idname = "pov.addsuperellipsoid" bl_label = "Add SuperEllipsoid" bl_description = "Create a SuperEllipsoid" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} # 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) 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') @classmethod def poll(cls, context): engine = context.scene.render.engine return (engine in cls.COMPAT_ENGINES) 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") return {'FINISHED'} class POVRAY_OT_superellipsoid_update(bpy.types.Operator): bl_idname = "pov.superellipsoid_update" bl_label = "Update" bl_description = "Update Superellipsoid" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): 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.object.mode_set(mode="OBJECT") pov_superellipsoid_define(context, None, context.object) return {'FINISHED'} def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): faces = [] if not vertIdx1 or not vertIdx2: return None 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): fan = True else: return None total = len(vertIdx2) if closed: if flipped: face = [ vertIdx1[0], vertIdx2[0], vertIdx2[total - 1]] if not fan: face.append(vertIdx1[total - 1]) faces.append(face) else: face = [vertIdx2[0], vertIdx1[0]] if not fan: face.append(vertIdx1[total - 1]) face.append(vertIdx2[total - 1]) faces.append(face) for num in range(total - 1): if flipped: if fan: face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]] else: 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]] faces.append(face) return faces def power(a,b): if a < 0: return -((-a)**b) return a**b 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) 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))? if i > 0: 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) 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 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_base = object_utils.object_data_add(context, mesh, operator=None) ob = ob_base.object 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): bl_idname = "pov.addsupertorus" bl_label = "Add Supertorus" bl_description = "Create a SuperTorus" 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'}) @classmethod def poll(cls, context): engine = context.scene.render.engine 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") return {'FINISHED'} class POVRAY_OT_supertorus_update(bpy.types.Operator): bl_idname = "pov.supertorus_update" bl_label = "Update" bl_description = "Update SuperTorus" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): 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.object.mode_set(mode="OBJECT") pov_supertorus_define(context, None, context.object) return {'FINISHED'} ######################################################################################################### class POVRAY_OT_loft_add(bpy.types.Operator): bl_idname = "pov.addloft" bl_label = "Add Loft Data" bl_description = "Create a Curve data for Meshmaker" 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): props = self.properties loftData = bpy.data.curves.new('Loft', type='CURVE') loftData.dimensions = '3D' loftData.resolution_u = 2 loftData.show_normal_face = False 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 r0 = 0.00001 z = -h/2 print("New") 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 nurbs = loftData.splines.new('NURBS') nurbs.points.add(len(coords)-1) for i, coord in enumerate(coords): 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 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 nurbs = loftData.splines.new('NURBS') nurbs.points.add(len(coords)-1) for i, coord in enumerate(coords): x,y,z = coord nurbs.points[i].co = (x, y, z, 1) nurbs.use_cyclic_u = True 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 nurbs = loftData.splines.new('NURBS') nurbs.points.add(len(coords)-1) for i, coord in enumerate(coords): 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): 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 nurbs = loftData.splines.new('NURBS') nurbs.points.add(len(coords)-1) for i, coord in enumerate(coords): 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) scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob ob.select = True ob.pov.curveshape = "loft" return {'FINISHED'} class POVRAY_OT_plane_add(bpy.types.Operator): bl_idname = "pov.addplane" bl_label = "Plane" bl_description = "Add Plane" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): layers = 20*[False] layers[0] = True bpy.ops.mesh.primitive_plane_add(radius = 100000,layers=layers) 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") 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): bl_idname = "pov.addbox" bl_label = "Box" bl_description = "Add Box" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): layers = 20*[False] layers[0] = True bpy.ops.mesh.primitive_cube_add(layers=layers) 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") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") ob.pov.object_as = "BOX" return {'FINISHED'} def pov_cylinder_define(context, op, ob, radius, loc, loc_cap): if op: R = op.R loc = bpy.context.scene.cursor_location loc_cap[0] = loc[0] loc_cap[1] = loc[1] 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. roteuler = rot.to_euler() if not ob: bpy.ops.object.add(type='MESH', location=loc) ob = context.object ob.name = ob.data.name = "PovCylinder" ob.pov.cylinder_radius = radius ob.pov.cylinder_location_cap = vec ob.pov.object_as = "CYLINDER" else: ob.location = loc 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_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) bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.shade_smooth() class POVRAY_OT_cylinder_add(bpy.types.Operator): bl_idname = "pov.addcylinder" bl_label = "Cylinder" bl_description = "Add Cylinder" bl_options = {'REGISTER', 'UNDO'} # XXX Keep it in sync with __init__'s cylinder Primitive 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)) imported_cyl_loc_cap = FloatVectorProperty( name="Imported Pov cap location", precision=6, default=(0.0, 0.0, 2.0)) def execute(self,context): props = self.properties R = props.R ob = context.object layers = 20*[False] layers[0] = True if ob: if ob.pov.imported_cyl_loc: LOC = ob.pov.imported_cyl_loc if ob.pov.imported_cyl_loc_cap: LOC_CAP = ob.pov.imported_cyl_loc_cap else: if not props.imported_cyl_loc: LOC_CAP = LOC = bpy.context.scene.cursor_location LOC_CAP[2] += 2.0 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") pov_cylinder_define(context, self, None, self.R, LOC, LOC_CAP) return {'FINISHED'} class POVRAY_OT_cylinder_update(bpy.types.Operator): bl_idname = "pov.cylinder_update" bl_label = "Update" bl_description = "Update Cylinder" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): ob = context.object radius = ob.pov.cylinder_radius loc = ob.location loc_cap = loc + ob.pov.cylinder_location_cap pov_cylinder_define(context, None, ob, radius, loc, loc_cap) return {'FINISHED'} ################################SPHERE########################################## def pov_sphere_define(context, op, ob, loc): if op: R = op.R loc = bpy.context.scene.cursor_location else: assert(ob) R = ob.pov.sphere_radius #keep object rotation and location for the add object operator obrot = ob.rotation_euler #obloc = ob.location obscale = ob.scale bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.reveal() bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.delete(type='VERT') bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, size=ob.pov.sphere_radius, location=loc, rotation=obrot) #bpy.ops.transform.rotate(axis=obrot,constraint_orientation='GLOBAL') bpy.ops.transform.resize(value=obscale) #bpy.ops.transform.rotate(axis=obrot, proportional_size=1) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.shade_smooth() #bpy.ops.transform.rotate(axis=obrot,constraint_orientation='GLOBAL') if not ob: bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, size=R, location=loc) ob = context.object ob.name = ob.data.name = "PovSphere" ob.pov.object_as = "SPHERE" ob.pov.sphere_radius = R bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_sphere_add(bpy.types.Operator): bl_idname = "pov.addsphere" bl_label = "Sphere" bl_description = "Add Sphere Shape" 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) imported_loc = FloatVectorProperty( name="Imported Pov location", precision=6, default=(0.0, 0.0, 0.0)) 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 else: if not props.imported_loc: LOC = bpy.context.scene.cursor_location else: LOC = props.imported_loc 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, layers=layers) # 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): bl_idname = "pov.sphere_update" bl_label = "Update" bl_description = "Update Sphere" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): pov_sphere_define(context, None, context.object,context.object.location) return {'FINISHED'} ####################################CONE####################################### def pov_cone_define(context, op, ob): verts = [] faces = [] if op: mesh = None base = op.base cap = op.cap seg = op.seg height = op.height else: assert(ob) mesh = ob.data base = ob.pov.cone_base_radius cap = ob.pov.cone_cap_radius seg = ob.pov.cone_segments height = ob.pov.cone_height zc = height / 2 zb = -zc angle = 2 * pi / seg t = 0 for i in range(seg): xb = base * cos(t) yb = base * sin(t) xc = cap * cos(t) yc = cap * sin(t) verts.append((xb, yb, zb)) verts.append((xc, yc, zc)) t += angle for i in range(seg): f = i * 2 if i == seg - 1: faces.append([0, 1, f + 1, f]) else: faces.append([f + 2, f + 3, f + 1, f]) if base != 0: base_face = [] for i in range(seg - 1, -1, -1): p = i * 2 base_face.append(p) faces.append(base_face) if cap != 0: cap_face = [] for i in range(seg): p = i * 2 + 1 cap_face.append(p) faces.append(cap_face) mesh = pov_define_mesh(mesh, verts, [], faces, "PovCone", True) if not ob: ob_base = object_utils.object_data_add(context, mesh, operator=None) ob = ob_base.object ob.pov.object_as = "CONE" ob.pov.cone_base_radius = base ob.pov.cone_cap_radius = cap ob.pov.cone_height = height ob.pov.cone_base_z = zb ob.pov.cone_cap_z = zc class POVRAY_OT_cone_add(bpy.types.Operator): bl_idname = "pov.cone_add" bl_label = "Cone" bl_description = "Add Cone" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} # XXX Keep it in sync with __init__'s RenderPovSettingsConePrimitive # 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) cap = FloatProperty( 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) height = FloatProperty( 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) 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") return {'FINISHED'} class POVRAY_OT_cone_update(bpy.types.Operator): bl_idname = "pov.cone_update" bl_label = "Update" bl_description = "Update Cone" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): 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.object.mode_set(mode="OBJECT") pov_cone_define(context, None, context.object) return {'FINISHED'} ######################################################################################################### class POVRAY_OT_isosurface_box_add(bpy.types.Operator): bl_idname = "pov.addisosurfacebox" bl_label = "Isosurface Box" bl_description = "Add Isosurface contained by Box" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): layers = 20*[False] layers[0] = True bpy.ops.mesh.primitive_cube_add(layers = layers) 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") ob.pov.object_as = "ISOSURFACE" ob.pov.contained_by = 'box' ob.name = 'Isosurface' return {'FINISHED'} class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator): bl_idname = "pov.addisosurfacesphere" bl_label = "Isosurface Sphere" bl_description = "Add Isosurface contained by Sphere" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): layers = 20*[False] layers[0] = True bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4,layers=layers) 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 = "ISOSURFACE" ob.pov.contained_by = 'sphere' ob.name = 'Isosurface' return {'FINISHED'} class POVRAY_OT_sphere_sweep_add(bpy.types.Operator): bl_idname = "pov.addspheresweep" bl_label = "Sphere Sweep" bl_description = "Create Sphere Sweep along curve" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): layers = 20*[False] layers[0] = True bpy.ops.curve.primitive_nurbs_curve_add(layers = layers) ob = context.object ob.name = ob.data.name = "PovSphereSweep" ob.pov.curveshape = "sphere_sweep" ob.data.bevel_depth = 0.02 ob.data.bevel_resolution = 4 ob.data.fill_mode = 'FULL' #ob.data.splines[0].order_u = 4 return {'FINISHED'} class POVRAY_OT_blob_add(bpy.types.Operator): bl_idname = "pov.addblobsphere" bl_label = "Blob Sphere" 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',layers = layers) ob = context.object ob.name = "Blob" return {'FINISHED'} class POVRAY_OT_rainbow_add(bpy.types.Operator): bl_idname = "pov.addrainbow" bl_label = "Rainbow" bl_description = "Add Rainbow" bl_options = {'REGISTER', 'UNDO'} def execute(self,context): cam = context.scene.camera bpy.ops.object.lamp_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 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 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 bpy.context.scene.objects.active = ob ob.select=True return {'FINISHED'} class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper): bl_idname = "pov.addheightfield" bl_label = "Height Field" bl_description = "Add Height Field " bl_options = {'REGISTER', 'UNDO'} # XXX Keep it in sync with __init__'s hf Primitive # 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) hf_gamma = FloatProperty( name="Gamma", description="Gamma", min=0.0001, max=20.0, default=1.0) hf_premultiplied = BoolProperty( name="Premultiplied", description="Premultiplied", default=True) 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) hf_hierarchy = BoolProperty( 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.image = img mat = bpy.data.materials.new('Tex_%s_hf'%im_name) hf_slot = mat.texture_slots.create(-1) hf_slot.texture = hf_tex 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,radius = 0.5,layers=layers) ob = context.object 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) 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 mat.texture_slots.clear(-1) bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") ob.pov.object_as = 'HEIGHT_FIELD' ob.pov.hf_filename = impath return {'FINISHED'} ############################TORUS############################################ def pov_torus_define(context, op, ob): if op: mas = op.mas mis = op.mis mar = op.mar mir = op.mir else: assert(ob) mas = ob.pov.torus_major_segments mis = ob.pov.torus_minor_segments mar = ob.pov.torus_major_radius mir = ob.pov.torus_minor_radius #keep object rotation and location for the add object operator obrot = ob.rotation_euler obloc = ob.location bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.reveal() bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.delete(type='VERT') bpy.ops.mesh.primitive_torus_add(rotation = obrot, location = obloc, major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") if not ob: bpy.ops.mesh.primitive_torus_add(major_segments=mas, minor_segments=mis,major_radius=mar, minor_radius=mir) ob = context.object ob.name = ob.data.name = "PovTorus" ob.pov.object_as = "TORUS" ob.pov.torus_major_segments = mas ob.pov.torus_minor_segments = mis ob.pov.torus_major_radius = mar ob.pov.torus_minor_radius = mir bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_torus_add(bpy.types.Operator): bl_idname = "pov.addtorus" bl_label = "Torus" bl_description = "Add Torus" 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): 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") return {'FINISHED'} class POVRAY_OT_torus_update(bpy.types.Operator): bl_idname = "pov.torus_update" bl_label = "Update" bl_description = "Update Torus" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): pov_torus_define(context, None, context.object) return {'FINISHED'} ################################################################################### class POVRAY_OT_prism_add(bpy.types.Operator): bl_idname = "pov.addprism" bl_label = "Prism" 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): props = self.properties loftData = bpy.data.curves.new('Prism', type='CURVE') loftData.dimensions = '2D' loftData.resolution_u = 2 loftData.show_normal_face = False loftData.extrude = 2 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 poly = loftData.splines.new('POLY') poly.points.add(len(coords)-1) for i, coord in enumerate(coords): x,y,z = coord poly.points[i].co = (x, y, z, 1) poly.use_cyclic_u = True ob = bpy.data.objects.new('Prism_shape', loftData) scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob ob.select = True ob.pov.curveshape = "prism" ob.name = ob.data.name = "Prism" return {'FINISHED'} ##############################PARAMETRIC###################################### def pov_parametric_define(context, op, ob): if op: u_min = op.u_min u_max = op.u_max v_min = op.v_min v_max = op.v_max x_eq = op.x_eq y_eq = op.y_eq z_eq = op.z_eq else: assert(ob) u_min = ob.pov.u_min u_max = ob.pov.u_max v_min = ob.pov.v_min v_max = ob.pov.v_max x_eq = ob.pov.x_eq y_eq = ob.pov.y_eq z_eq = ob.pov.z_eq #keep object rotation and location for the updated object obloc = ob.location obrot = ob.rotation_euler # In radians #Parametric addon has no loc rot, some extra work is needed #in case cursor has moved curloc = bpy.context.scene.cursor_location bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.reveal() bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.delete(type='VERT') bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) bpy.ops.mesh.select_all(action='SELECT') #extra work: bpy.ops.transform.translate(value=(obloc-curloc), proportional_size=1) bpy.ops.transform.rotate(axis=obrot, proportional_size=1) bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") if not ob: bpy.ops.mesh.primitive_xyz_function_surface(x_eq=x_eq, y_eq=y_eq, z_eq=z_eq, range_u_min=u_min, range_u_max=u_max, range_v_min=v_min, range_v_max=v_max) ob = context.object ob.name = ob.data.name = "PovParametric" ob.pov.object_as = "PARAMETRIC" ob.pov.u_min = u_min ob.pov.u_max = u_max ob.pov.v_min = v_min ob.pov.v_max = v_max ob.pov.x_eq = x_eq ob.pov.y_eq = y_eq ob.pov.z_eq = z_eq bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) bpy.ops.object.mode_set(mode="OBJECT") class POVRAY_OT_parametric_add(bpy.types.Operator): bl_idname = "pov.addparametric" bl_label = "Parametric" bl_description = "Add Paramertic" 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): props = self.properties u_min = props.u_min v_min = props.v_min u_max = props.u_max v_max = props.v_max x_eq = props.x_eq y_eq = props.y_eq 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") return {'FINISHED'} class POVRAY_OT_parametric_update(bpy.types.Operator): bl_idname = "pov.parametric_update" bl_label = "Update" bl_description = "Update parametric object" bl_options = {'REGISTER', 'UNDO'} COMPAT_ENGINES = {'POVRAY_RENDER'} @classmethod 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) def execute(self, context): pov_parametric_define(context, None, context.object) return {'FINISHED'} ####################################################################### class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator): bl_idname = "pov.addpolygontocircle" bl_label = "Polygon To Circle Blending" bl_description = "Add Polygon To Circle Blending Surface" bl_options = {'REGISTER', 'UNDO'} 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): 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=layers) bpy.ops.transform.translate(value=(0, 0, 1)) bpy.ops.mesh.subdivide(number_cuts=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, layers=layers) 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, layers=layers) bpy.ops.transform.translate(value=(0, 0, 1)) bpy.ops.mesh.select_all(action='SELECT') bpy.ops.mesh.remove_doubles() bpy.ops.object.mode_set(mode='OBJECT') ob = context.object ob.name = "Polygon_To_Circle" ob.pov.object_as = 'POLYCIRCLE' ob.pov.ngon = ngon ob.pov.ngonR = ngonR ob.pov.circleR = circleR bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.hide(unselected=False) 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'} COMPAT_ENGINES = {'POVRAY_RENDER'} # ----------- # 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) def execute(self, context): from mathutils import Matrix verts = [] faces = [] materials = [] blendMats = [] ############## povMats = [] ############## colors = [] matNames = [] lenverts = None lenfaces = None suffix = -1 name = 'Mesh2_%s'%suffix name_search = False verts_search = False faces_search = False plane_search = False box_search = False cylinder_search = False sphere_search = False cone_search = False tex_search = False ################## cache = [] matrixes = {} writematrix = False index = None value = None #filepov = bpy.path.abspath(self.filepath) #was used for single files def mat_search(cache): r = g = b = 0.5 f = t = 0 color = None for item, value in enumerate(cache): if value == 'texture': pass if value == 'pigment': if cache[item+2] in {'rgb','srgb'}: pass elif cache[item+2] in {'rgbf','srgbf'}: pass 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]) except: r = g = b = t = float(cache[item+2]) color = (r,g,b,t) elif cache[item+2] in {'rgbft','srgbft'}: pass else: 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) else: for i, value in enumerate(colors): if color == value: ob.data.materials.append(bpy.data.materials[matNames[i]]) for file in self.files: 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(","," ") lw = string.split() lenwords = len(lw) if lw: if lw[0] == "object": writematrix = True if writematrix: 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 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 = S.split() lenS= len(S) for i,word in enumerate(S): ##################Primitives Import################## if word == 'cone': cone_search = True name_search = False if cone_search: cache.append(word) if cache[-1] == '}': try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) r0 = float(cache[5]) x1 = float(cache[6]) y1 = float(cache[7]) 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)) ob = context.object ob.location = (x0,y0,z0) #ob.scale = (r,r,r) mat_search(cache) except (ValueError): pass cache = [] cone_search = False if word == 'plane': plane_search = True name_search = False if plane_search: cache.append(word) if cache[-1] == '}': try: bpy.ops.pov.addplane() ob = context.object mat_search(cache) except (ValueError): pass cache = [] plane_search = False if word == 'box': box_search = True name_search = False if box_search: cache.append(word) if cache[-1] == '}': try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) 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) bpy.ops.pov.addbox() ob = context.object ob.location = center mat_search(cache) except (ValueError): pass cache = [] box_search = False if word == 'cylinder': cylinder_search = True name_search = False if cylinder_search: cache.append(word) if cache[-1] == '}': try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) 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) r = float(cache[8]) 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) ob = context.object ob.location = (x0, y0, z0) ob.rotation_euler = rot.to_euler() ob.scale = (1,1,scaleZ) #scale data rather than obj? # bpy.ops.object.mode_set(mode='EDIT') # bpy.ops.mesh.reveal() # bpy.ops.mesh.select_all(action='SELECT') # bpy.ops.transform.resize(value=(1,1,scaleZ), constraint_orientation='LOCAL') # bpy.ops.mesh.hide(unselected=False) # bpy.ops.object.mode_set(mode='OBJECT') mat_search(cache) except (ValueError): pass cache = [] cylinder_search = False if word == 'sphere': sphere_search = True name_search = False if sphere_search: cache.append(word) if cache[-1] == '}': x = y = z = r = 0 try: x = float(cache[2]) y = float(cache[3]) z = float(cache[4]) r = float(cache[5]) except (ValueError): pass except: x = y = z = float(cache[2]) 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) mat_search(cache) cache = [] sphere_search = False ##################End Primitives Import################## if word == '#declare': name_search = True if name_search: cache.append(word) if word == 'mesh2': name_search = False if cache[-2] == '=': name = cache[-3] else: suffix+=1 cache = [] if word in {'texture',';'}: name_search = False cache = [] if word == 'vertex_vectors': verts_search = True if verts_search: cache.append(word) if word == '}': verts_search = False 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]))) 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': tex_search = False ################ faces_search = True if faces_search: cache.append(word) if word == '}': faces_search = False lenfaces = cache[2] cache.pop() cache.pop(0) cache.pop(0) cache.pop(0) lf = int(lenfaces) 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]))) if var == 4: 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]))) 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_base = object_utils.object_data_add(context, mesh, operator=None) #ob = ob_base.object me = bpy.data.meshes.new(name) ######## ob = bpy.data.objects.new(name, me) ########## bpy.context.scene.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 = [] ######################### cache = [] name_search = True 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[0][0] = v[0] matrix[1][0] = v[1] matrix[2][0] = v[2] matrix[0][1] = v[3] matrix[1][1] = v[4] matrix[2][1] = v[5] matrix[0][2] = v[6] matrix[1][2] = v[7] matrix[2][2] = v[8] matrix[0][3] = v[9] matrix[1][3] = v[10] matrix[2][3] = v[11] 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]]) ##To keep Avogadro Camera angle: # for obj in bpy.context.scene.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) return {'FINISHED'}