Newer
Older
# SPDX-License-Identifier: GPL-2.0-or-later
"""Import, export and render to POV engines.
These engines can be POV-Ray or Uberpov but others too, since POV is a
Scene Description Language. The script has been split in as few files
Provide property buttons for the user to set up the variables
scenography_properties.py
Initialize properties for translating Blender cam/light/environment parameters to pov
Maurice Raybaud
committed
scenography_gui.py :
Display cam/light/environment properties from scenography_properties.py for user to change them
scenography.py
Translate cam/light/environment properties to corresponding pov features
object_properties.py :
nitialize properties for translating Blender objects parameters to pov
object_primitives.py :
Display some POV native primitives in 3D view for input and output
object_mesh_topology.py :
Translate to POV the meshes geometries
object_curve_topology.py :
Translate to POV the curve based geometries
object_particles.py :
Translate to POV the particle based geometries
object_gui.py :
Display properties from object_properties.py for user to change them
Maurice Raybaud
committed
shading_properties.py :
Initialize properties for translating Blender materials parameters to pov
Maurice Raybaud
committed
shading_nodes.py :
Maurice Raybaud
committed
shading_gui.py :
Display properties from shading_properties.py for user to change them
Translate shading properties to declared textures at the top of a pov file
Maurice Raybaud
committed
texturing_properties.py :
Initialize properties for translating Blender materials /world... texture influences to pov
Maurice Raybaud
committed
texturing_gui.py :
Display properties from texturing_properties.py for user to change them
Maurice Raybaud
committed
texturing.py :
Translate blender texture influences into POV
render_properties.py :
Initialize properties for render parameters (Blender and POV native)
render_gui.py :
Display properties from render_properties.py for user to change them
Translate render properties (Blender and POV native) to POV, ini file and bash
scripting_properties.py :
Initialize properties for scene description language parameters (POV native)
scripting_gui.py :
Display properties from scripting_properties.py for user to add his custom POV code
scripting.py :
Insert POV native scene description elements into blender scene or to exported POV file
Maurice Raybaud
committed
df3_library.py :
Maurice Raybaud
committed
update_files.py :
Update new variables to values from older API. This file needs an update
Along these essential files also coexist a few additional libraries to help make
Blender stand up to other POV IDEs such as povwin or QTPOV
apple.py ; chicken.py ; cream.py ; Ketchup.py ; marble.py ;
potato.py ; skim_milk.py ; skin1.py ; skin2.py ; whole_milk.py
Radiosity
01_Debug.py ; 02_Fast.py ; 03_Normal.py ; 04_Two_Bounces.py ;
05_Final.py ; 06_Outdoor_Low_Quality.py ; 07_Outdoor_High_Quality.py ;
08_Outdoor(Sun)Light.py ; 09_Indoor_Low_Quality.py ;
10_Indoor_High_Quality.py ;
World
01_Clear_Blue_Sky.py ; 02_Partly_Hazy_Sky.py ; 03_Overcast_Sky.py ;
04_Cartoony_Sky.py ; 05_Under_Water.py ;
Light
01_(4800K)_Direct_Sun.py ;
02_(5400K)_High_Noon_Sun.py ;
03_(6000K)_Daylight_Window.py ;
04_(6000K)_2500W_HMI_(Halogen_Metal_Iodide).py ;
05_(4000K)_100W_Metal_Halide.py ;
06_(3200K)_100W_Quartz_Halogen.py ;
07_(2850K)_100w_Tungsten.py ;
08_(2600K)_40w_Tungsten.py ;
09_(5000K)_75W_Full_Spectrum_Fluorescent_T12.py ;
10_(4300K)_40W_Vintage_Fluorescent_T12.py ;
11_(5000K)_18W_Standard_Fluorescent_T8 ;
12_(4200K)_18W_Cool_White_Fluorescent_T8.py ;
14_(6500K)_54W_Grow_Light_Fluorescent_T5-HO.py ;
15_(3200K)_40W_Induction_Fluorescent.py ;
16_(2100K)_150W_High_Pressure_Sodium.py ;
17_(1700K)_135W_Low_Pressure_Sodium.py ;
18_(6800K)_175W_Mercury_Vapor.py ;
19_(5200K)_700W_Carbon_Arc.py ;
20_(6500K)_15W_LED_Spot.py ;
21_(2700K)_7W_OLED_Panel.py ;
23_(30000K)_40W_Black_Light_Bulb.py;
24_(1850K)_Candle.py
templates:
abyss.pov ; biscuit.pov ; bsp_Tango.pov ; chess2.pov ;
cornell.pov ; diffract.pov ; diffuse_back.pov ; float5 ;
gamma_showcase.pov ; grenadine.pov ; isocacti.pov ;
mediasky.pov ; patio-radio.pov ; subsurface.pov ; wallstucco.pov
"""
Maurice Raybaud
committed
'name': "Persistence of Vision",
'author': "Campbell Barton, "
"Maurice Raybaud, "
"Leonid Desyatkov, "
"Bastien Montagne, "
"Constantin Rahn, "
"Silvio Falcinelli,"
"Paco García",
"version": (0, 1, 2),
Maurice Raybaud
committed
'blender': (2, 81, 0),
'location': "Render Properties > Render Engine > Persistence of Vision",
'description': "Persistence of Vision integration for blender",
'doc_url': "{BLENDER_MANUAL_URL}/addons/render/povray.html",
'category': "Render",
'warning': "Co-maintainers welcome",
# Other occasional contributors, more or less in chronological order:
# Luca Bonavita ; Shane Ambler ; Brendon Murphy ; Doug Hammond ;
# Thomas Dinges ; Jonathan Smith ; Sebastian Nell ; Philipp Oeser ;
# Sybren A. Stüvel ; Dalai Felinto ; Sergey Sharybin ; Brecht Van Lommel ;
# Stephen Leger ; Rune Morling ; Aaron Carlisle ; Ankit Meel ;
importlib.reload(base_ui)
importlib.reload(shading_nodes)
importlib.reload(scenography_properties)
importlib.reload(scenography)
importlib.reload(render_properties)
importlib.reload(render_gui)
importlib.reload(render)
importlib.reload(shading_properties)
importlib.reload(shading_gui)
importlib.reload(texturing_properties)
importlib.reload(texturing_gui)
importlib.reload(texturing)
importlib.reload(object_properties)
importlib.reload(object_gui)
importlib.reload(object_mesh_topology)
importlib.reload(object_curve_topology)
importlib.reload(object_primitives)
importlib.reload(scripting_gui)
importlib.reload(update_files)
from bpy.utils import register_class, unregister_class
from bpy.props import StringProperty, BoolProperty, EnumProperty
from . import (
base_ui,
render_properties,
scenography_properties,
shading_properties,
texturing_properties,
object_properties,
scripting_properties,
render,
object_primitives, # for import and export of POV specific primitives
)
# ---------------------------------------------------------------- #
# ---------------------------------------------------------------- #
Maurice Raybaud
committed
"""Update this addon to the latest version"""
bl_idname = "pov.update_addon"
bl_label = "Update POV addon"
def execute(self, context): # sourcery no-metrics
import os
import tempfile
import shutil
import urllib.request
import urllib.error
import zipfile
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
if ignore is not None:
ignored = ignore(src, files)
else:
ignored = set()
for f in files:
if f not in ignored:
recursive_overwrite(os.path.join(src, f), os.path.join(dest, f), ignore)
else:
shutil.copyfile(src, dest)
Maurice Raybaud
committed
print("-" * 20)
print("Updating POV addon...")
with tempfile.TemporaryDirectory() as temp_dir_path:
temp_zip_path = os.path.join(temp_dir_path, 'master.zip')
# Download zip archive of latest addons master branch commit
# More work needed so we also get files from the shared addons presets /pov folder
# switch this URL back to the BF hosted one as soon as gitweb snapshot gets fixed
url = 'https://github.com/blender/blender-addons/archive/refs/heads/master.zip'
try:
Maurice Raybaud
committed
print("Downloading", url)
with urllib.request.urlopen(url, timeout=60) as url_handle, open(
temp_zip_path, 'wb'
) as file_handle:
file_handle.write(url_handle.read())
except urllib.error.URLError as err:
Maurice Raybaud
committed
self.report({'ERROR'}, "Could not download: %s" % err)
Maurice Raybaud
committed
print("Extracting ZIP archive")
with zipfile.ZipFile(temp_zip_path) as zip_archive:
for member in zip_archive.namelist():
if 'blender-addons-master/render_povray' in member:
# Remove the first directory and the filename
# e.g. blender-addons-master/render_povray/shading_nodes.py
# becomes render_povray/shading_nodes.py
target_path = os.path.join(
temp_dir_path, os.path.join(*member.split('/')[1:-1])
)
filename = os.path.basename(member)
# Skip directories
if len(filename) == 0:
continue
# Create the target directory if necessary
if not os.path.exists(target_path):
os.makedirs(target_path)
Maurice Raybaud
committed
source = zip_archive.open(member)
target = open(os.path.join(target_path, filename), "wb")
with source, target:
shutil.copyfileobj(source, target)
print('copying', source, 'to', target)
extracted_render_povray_path = os.path.join(temp_dir_path, 'render_povray')
if not os.path.exists(extracted_render_povray_path):
Maurice Raybaud
committed
self.report({'ERROR'}, "Could not extract ZIP archive! Aborting.")
return {'FINISHED'}
# Find the old POV addon files
render_povray_dir = os.path.abspath(os.path.dirname(__file__))
Maurice Raybaud
committed
print("POV addon addon folder:", render_povray_dir)
# Delete old POV addon files
# (only directories and *.py files, user might have other stuff in there!)
Maurice Raybaud
committed
print("Deleting old POV addon files")
# remove __init__.py
os.remove(os.path.join(render_povray_dir, '__init__.py'))
# remove all folders
DIRNAMES = 1
Maurice Raybaud
committed
for directory in next(os.walk(render_povray_dir))[DIRNAMES]:
shutil.rmtree(os.path.join(render_povray_dir, directory))
Maurice Raybaud
committed
print("Copying new POV addon files")
# copy new POV addon files
# copy __init__.py
shutil.copy2(
os.path.join(extracted_render_povray_path, '__init__.py'), render_povray_dir
# copy all folders
recursive_overwrite(extracted_render_povray_path, render_povray_dir)
Maurice Raybaud
committed
print("POV addon update finished, restart Blender for the changes to take effect.")
print("-" * 20)
self.report({'WARNING'}, "Restart Blender!")
# ---------------------------------------------------------------- #
# ---------------------------------------------------------------- #
class PovrayPreferences(bpy.types.AddonPreferences):
Maurice Raybaud
committed
"""Declare preference variables to set up POV binary"""
Maurice Raybaud
committed
name='Feature Set',
description='Choose between official (POV-Ray) or (UberPOV) '
'development branch features to write in the pov file',
Maurice Raybaud
committed
('povray', 'Official POV-Ray', '', 'PLUGIN', 0),
('uberpov', 'Unofficial UberPOV', '', 'PLUGIN', 1),
Maurice Raybaud
committed
default='povray',
Maurice Raybaud
committed
name='Binary Location', description='Path to renderer executable', subtype='FILE_PATH'
Maurice Raybaud
committed
name='Includes Location', description='Path to Insert Menu files', subtype='FILE_PATH'
Maurice Raybaud
committed
name='Use Sound',
description='Signaling end of the render process at various'
'stages can help if you\'re away from monitor',
Maurice Raybaud
committed
# TODO: Auto find POV sound directory as it does for binary
# And implement the three cases, left uncommented for a dummy
# interface in case some doc screenshots get made for that area
filepath_complete_sound: StringProperty(
Maurice Raybaud
committed
name='Finish Render Sound',
description='Path to finished render sound file',
subtype='FILE_PATH',
Maurice Raybaud
committed
name='Parse Error Sound',
description='Path to parsing time error sound file',
subtype='FILE_PATH',
Maurice Raybaud
committed
Maurice Raybaud
committed
name='Cancel Render Sound',
description='Path to cancelled or render time error sound file',
subtype='FILE_PATH',
def draw(self, context):
layout = self.layout
layout.prop(self, "branch_feature_set_povray")
layout.prop(self, "filepath_povray")
layout.prop(self, "docpath_povray")
layout.prop(self, "filepath_complete_sound")
layout.prop(self, "filepath_parse_error_sound")
layout.prop(self, "filepath_cancel_sound")
layout.prop(self, "use_sounds", icon="SOUND")
layout.operator("pov.update_addon", icon='FILE_REFRESH')
classes = (
POV_OT_update_addon,
PovrayPreferences,
)
def register():
for cls in classes:
register_class(cls)
render_properties.register()
scenography_properties.register()
shading_properties.register()
texturing_properties.register()
object_properties.register()
scripting_properties.register()
render.register()
base_ui.register()
object_primitives.register()
def unregister():
object_primitives.unregister()
base_ui.unregister()
render.unregister()
scripting_properties.unregister()
object_properties.unregister()
texturing_properties.unregister()
shading_properties.unregister()
scenography_properties.unregister()
render_properties.unregister()
# ------------8<---------[ BREAKPOINT ]--------------8<----------- # Move this snippet around
# __import__('code').interact(local=dict(globals(), **locals())) # < and uncomment this line
# ---------------------------------------------------------------- # to inspect from Terminal