Skip to content

Instantly share code, notes, and snippets.

@runiq
Last active December 17, 2015 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save runiq/5669624 to your computer and use it in GitHub Desktop.
Save runiq/5669624 to your computer and use it in GitHub Desktop.
PyMOL POV-Ray ambient occlusion rendering
# make_pov.py
#
# Original script written by Robert Campbell
# Modified by Tsjerk A. Wassenaar and Patrice Peterson
from os.path import splitext
from pymol import cmd
def make_pov(file, name="PymolObject", clip=False):
f1, f2 = file, splitext(file)[0] + '.inc'
# We don't use the original header but construct our own
_, data = cmd.get_povray()
with open(f1,'w') as povfile:
# #version directive is mandatory since 3.7
# Default settings are imported from an inlcude file
povfile.write("""#version 3.7;
#include \"pymoldefaultsettings.inc\"
""")
# Get PyMOL view
povview = cmd.get_view()
# r11, r12, r13 - 3x3 Rotation matrix (model space to camera space)
# r21, r22, r23
# r31, r32, r33
# c1, c2, c3 - Vector from camera position to origin of rotation (camera space)
# o1, o2, o3 - Origin of rotation (model space)
# s1, s2, or - Slab near and far, FOV flag
# Light source
# TODO:
# - Lighting position and size
povfile.write("""
// Weak highlight within the sky sphere
light_source {
500
// Light intensity depends on color brightness
rgb .5
// Cylindrical and spot lights can be area lights as well
area_light 100*x, 100*y, 100, 100
// Automatically adapt number of light sources
adaptive 1
// Add random positional noise to light source positions
jitter
// Use circular area light
circular
// Always normalize the light area with regard to the ray
orient
}
// invisible pseudo-sky sphere
sphere {
0, 1
pigment {
color rgb 1
}
finish {
emission .5
}
// make sure the sphere is big enough to cover the entire scene
scale 1000
hollow
// make sphere invisible for direct rays
no_image
}
""")
# Camera
viewport_x, viewport_y = cmd.get_viewport()
x_ratio = float(viewport_x)/viewport_y
if povview[17] < 0:
camtype = "perspective"
else:
camtype = "orthographic"
povfile.write("""
camera {
%s
location <0.0, 0.0, 0.0>
// original aspect ratio: w:h = %s:1
// Account for left-right mirroring
right -x*image_width/image_height
up y
angle %s
look_at <0.0, 0.0, -1.0>
}
""" % (camtype, x_ratio, abs(povview[17])))
# Finally, the molecule data itself
if clip:
objtype = "difference"
objclip = ""
if clip in ["near","both"]:
objclip = objclip + "plane { z, -%f }" % povview[15]
if clip in ["far","both"]:
objclip = objclip + "plane { z, -%f }" % povview[16]
else:
objtype = "object"
objclip = ""
povfile.write("""
#declare %s = union { #include "%s" }
%s { %s %s }
""" % (name, f2, objtype, name, objclip ) )
with open(f2,'w') as povfile:
povfile.write(data)
cmd.extend('make_pov',make_pov)
// PyMOL default settings file
// automatically included by the make_pov script
global_settings {
assumed_gamma 2.2
adc_bailout 1/255
charset utf8
// 1 unit in coordinate system = 1 cm
// To calculate SSLT for different materials
mm_per_unit 10
// Only with +q9 or higher
subsurface {
// Number of sample rays for diffuse (first value) and single
// (second value) scattering
// Lower values -> better performance
samples 50, 50
// Use subsurface scattering on radiosity photons
radiosity on
}
radiosity {
gray_threshold 0.0
brightness 1
// not smaller than 0.0039
adc_bailout 0.005
// not lower than 2 for isosurfaces, not bigger than 3
recursion_limit 3
// lowers error bound during pretrace, removes blotches (default 0.5)
low_error_factor 0.5
// Fraction of screen to follow bounced rays (default 0.015)
// Too small → rendering gets slow; too high → no natural darkening
// of crevices as rays get reused
minimum_reuse 0.015
maximum_reuse 0.2
// Min and maxsize of block in mosaic preview during pretrace
// default 0.08
pretrace_start 0.08
// not smaller than 0.02 (default 0.04)
pretrace_end 0.04
count 150
// Max number of radiosity values to be blended together (default
// 4, max 20)
// Smaller than 4 → patchiness
nearest_count 10
// lower error bound → more artifacts (requires higher count), but
// also higher quality
error_bound 0.4
}
}
// default texture
#default {
finish {
diffuse 0.6
specular 0.7
roughness 0.12
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment