Skip to content
Snippets Groups Projects
__init__.py 15.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • # SPDX-License-Identifier: GPL-2.0-or-later
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    # <pep8 compliant>
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    """Import, export and render to POV engines.
    
    These engines can be POV-Ray or Uberpov but others too, since POV is a
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    Scene Description Language. The script has been split in as few files
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    as possible :
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    __init__.py :
    
        Initialize properties
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    base_ui.py :
    
        Provide property buttons for the user to set up the variables
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    scenography_properties.py
        Initialize properties for translating Blender cam/light/environment parameters to pov
    
    
    scenography_gui.py :
        Display cam/light/environment properties from scenography_properties.py for user to change them
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    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's avatar
    Maurice Raybaud committed
        Initialize properties for translating Blender materials parameters to pov
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Translate node trees to the pov file
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Display properties from shading_properties.py for user to change them
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    shading.py
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Translate shading properties to declared textures at the top of a pov file
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Initialize properties for translating Blender materials /world... texture influences to pov
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Display properties from texturing_properties.py for user to change them
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    render.py :
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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's avatar
    Maurice Raybaud committed
        Render smoke to *.df3 files
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Update new variables to values from older API. This file needs an update
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        presets :
            Material (sss)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                apple.py ; chicken.py ; cream.py ; Ketchup.py ; marble.py ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                potato.py ; skim_milk.py ; skin1.py ; skin2.py ; whole_milk.py
            Radiosity
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                01_Debug.py ; 02_Fast.py ; 03_Normal.py ; 04_Two_Bounces.py ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                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 ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                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 ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                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 ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                13_(3000K)_18W_Warm_Fluorescent_T8.py ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                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 ;
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                22_(30000K)_40W_Black_Light_Fluorescent.py ;
    
                23_(30000K)_40W_Black_Light_Bulb.py;
                24_(1850K)_Candle.py
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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
    """
    
    
    
        'name': "Persistence of Vision",
        'author': "Campbell Barton, "
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                  "Maurice Raybaud, "
                  "Leonid Desyatkov, "
                  "Bastien Montagne, "
                  "Constantin Rahn, "
                  "Silvio Falcinelli,"
                  "Paco García",
                  "version": (0, 1, 2),
    
        '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",
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    # 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 ;
    
    
    if "bpy" in locals():
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        importlib.reload(shading_properties)
        importlib.reload(shading_gui)
    
        importlib.reload(shading)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        from bpy.props import StringProperty, BoolProperty, EnumProperty
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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's avatar
    Maurice Raybaud committed
    # Auto update.
    
    # ---------------------------------------------------------------- #
    
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    class POV_OT_update_addon(bpy.types.Operator):
    
        """Update this addon to the latest version"""
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
        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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
            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's avatar
    Maurice Raybaud committed
    
            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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # 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's avatar
    Maurice Raybaud committed
    
                    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:
    
                    self.report({'ERROR'}, "Could not download: %s" % err)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                # Extract the zip
    
                print("Extracting ZIP archive")
                with zipfile.ZipFile(temp_zip_path) as zip_archive:
                    for member in zip_archive.namelist():
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        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's avatar
    Maurice Raybaud committed
                            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):
    
                    self.report({'ERROR'}, "Could not extract ZIP archive! Aborting.")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    return {'FINISHED'}
    
                # Find the old POV addon files
                render_povray_dir = os.path.abspath(os.path.dirname(__file__))
    
                print("POV addon addon folder:", render_povray_dir)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                # TODO: Create backup
    
    
                # Delete old POV addon files
                # (only directories and *.py files, user might have other stuff in there!)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # remove __init__.py
                os.remove(os.path.join(render_povray_dir, '__init__.py'))
                # remove all folders
                DIRNAMES = 1
    
                for directory in next(os.walk(render_povray_dir))[DIRNAMES]:
                    shutil.rmtree(os.path.join(render_povray_dir, directory))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # copy new POV addon files
                # copy __init__.py
                shutil.copy2(
                    os.path.join(extracted_render_povray_path, '__init__.py'), render_povray_dir
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # copy all folders
                recursive_overwrite(extracted_render_povray_path, render_povray_dir)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            bpy.ops.preferences.addon_refresh()
    
            print("POV addon update finished, restart Blender for the changes to take effect.")
            print("-" * 20)
            self.report({'WARNING'}, "Restart Blender!")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            return {'FINISHED'}
    
    # ---------------------------------------------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    # Povray Preferences.
    
    # ---------------------------------------------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    class PovrayPreferences(bpy.types.AddonPreferences):
    
        """Declare preference variables to set up POV binary"""
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        bl_idname = __name__
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        branch_feature_set_povray: EnumProperty(
    
            name='Feature Set',
            description='Choose between official (POV-Ray) or (UberPOV) '
                        'development branch features to write in the pov file',
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            items=(
    
                ('povray', 'Official POV-Ray', '', 'PLUGIN', 0),
                ('uberpov', 'Unofficial UberPOV', '', 'PLUGIN', 1),
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        filepath_povray: StringProperty(
    
            name='Binary Location', description='Path to renderer executable', subtype='FILE_PATH'
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        docpath_povray: StringProperty(
    
            name='Includes Location', description='Path to Insert Menu files', subtype='FILE_PATH'
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        use_sounds: BoolProperty(
    
            name='Use Sound',
            description='Signaling end of the render process at various'
                        'stages can help if you\'re away from monitor',
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            default=False,
        )
    
    Maurice Raybaud's avatar
    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(
    
            name='Finish Render Sound',
            description='Path to finished render sound file',
            subtype='FILE_PATH',
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        filepath_parse_error_sound: StringProperty(
    
            name='Parse Error Sound',
            description='Path to parsing time error sound file',
            subtype='FILE_PATH',
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        filepath_cancel_sound: StringProperty(
    
            name='Cancel Render Sound',
            description='Path to cancelled or render time error sound file',
            subtype='FILE_PATH',
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    classes = (
        POV_OT_update_addon,
        PovrayPreferences,
    )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    def register():
        for cls in classes:
            register_class(cls)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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()
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    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()
    
        for cls in reversed(classes):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            unregister_class(cls)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    if __name__ == "__main__":
        register()
    
    # ------------8<---------[ BREAKPOINT ]--------------8<----------- #  Move this snippet around
    # __import__('code').interact(local=dict(globals(), **locals()))   # < and uncomment this line
    # ---------------------------------------------------------------- #  to inspect from Terminal