Skip to content
Snippets Groups Projects
render.py 315 KiB
Newer Older
  • Learn to ignore specific revisions
  • 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495
                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({'WARNING'}, "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({'WARNING'}, "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 ImportAvogadroPOV(bpy.types.Operator, ImportHelper):
        """Load Povray File as output by Avogadro"""
        bl_idname = "import_scene.avogadro"
        bl_label = "Import POV Avogadro"
        bl_options = {'PRESET', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        filename_ext = ".pov"
        filter_glob = StringProperty(
                default="*.pov",
                options={'HIDDEN'},
                )
    
        def execute(self, context):
            coords=[]
            colors = []
            matNames = []
            xall = yall = zall = []
            layers = 20*[False]
            layers[0] = True
            ob = None
            camloc = (0,0,0)
            filepov = bpy.path.abspath(self.filepath)
            for line in open(filepov):
                string = line.replace("<"," ")
                chars = [">","{","}",","]
                for symbol in chars:
                    string = string.replace(symbol," ")
                split = string.split()
                if split and split[0] == "location":
                    x = float(split[1])
                    y = float(split[2])
                    z = float(split[3])
                    camloc = ((x,y,z))
                if split and len(split) == 7:
                    try:
                        x1 = float(split[0])
                        coords.append(x1)
                    except:
                        pass
                    if coords != []:            
                        x1 = float(split[0])
                        y1 = float(split[1])
                        z1 = float(split[2])
                        x2 = float(split[3])
                        y2 = float(split[4])
                        z2 = float(split[5])
                        xall.append(x1)
                        yall.append(y1)
                        zall.append(z1)
                        xall.append(x2)
                        yall.append(y2)
                        zall.append(z2)
                        radius = float(split[6])
                        curveData = bpy.data.curves.new('myCurve', type='CURVE')
                        curveData.dimensions = '3D'
                        curveData.resolution_u = 2
                        curveData.fill_mode = "FULL"
                        curveData.bevel_depth = radius
                        curveData.bevel_resolution = 5
                        polyline = curveData.splines.new('POLY')
                        polyline.points.add(1) 
                        polyline.points[0].co = (x1, y1, z1, 1)
                        polyline.points[1].co = (x2, y2, z2, 1)
                        ob = bpy.data.objects.new('myCurve', curveData)
                        scn = bpy.context.scene
                        scn.objects.link(ob)
                        scn.objects.active = ob
                        ob.select = True
                        bpy.ops.object.convert(target='MESH',keep_original=False)
                        #XXX TODO use a PovCylinder instead of mesh 
                        #but add end points and radius to addPovcylinder op first
                        ob.select=False
                        coords = []
                if split and len(split) == 4:
                    try:
                        x = float(split[0])
                        coords.append(x)
                    except:
                        pass
                    if coords != []:
                        x = float(split[0])
                        y = float(split[1])
                        z = float(split[2])
                        xall.append(x)
                        yall.append(y)
                        zall.append(z)
                        radius = float(split[3])
                        
    
                        ob.pov.imported_loc=(x, y, z)
                        bpy.ops.pov.addsphere(R=radius, imported_loc=(x, y, z))
                        bpy.ops.object.shade_smooth()
                        ob = bpy.context.object
                        coords = []        
                if split and len(split) == 6:
                    if split[0] == "pigment":
                        r,g,b,t = float(split[2]),float(split[3]),float(split[4]),float(split[5])
                        color = (r,g,b,t)
                        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
                            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]])
            x0 = min(xall)
            x1 = max(xall)
            y0 = min(yall)
            y1 = max(yall)
            z0 = min(zall)
            z1 = max(zall)
            x = (x0+x1)/2
            y = (y0+y1)/2
            z = (z0+z1)/2
            bpy.ops.object.empty_add(layers=layers)
            ob = bpy.context.object
            ob.location = ((x,y,z))
            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 = camloc
            for obj in bpy.context.scene.objects:
                if obj.type == "LAMP":
                    obj.location = camloc
                    obj.pov.light_type = "shadowless"
                    break
            return {'FINISHED'}