3
$\begingroup$

My problem is as following:

I want to create custom rendering settings for Blender, that will set up the camera and the screen resolution - initialize an isometric projection, basing on the target tile width given in pixels.

I can do almost everything: I've created a Panel in the "RENDER" tab in the Properties view, and I've created an operator which will render everything and export the sprites in a designed format.

The only thing that is left is that I can't create controls for the settings that need to be there: the slider for the tile width, or perhaps other settings - I need to be able to read this values when the addon renders stuff.

The UILayout "layout" object that I can get from "self.layout" in the panels draw method has a method called "prop", but it requires an instance of an ID class object or OperatorProperties instance (the docs say it needs AnyType but in order . The first would work if I've kept the data per Object or per Scene basis. But I don't really know if this is a good idea.

This is a stub of what I got:

import bpy

bl_info = { 
    "name":     "Render ISO", 
    "category": "Render"  # perhaps wrong
}



class RenderIsoOperator(bpy.types.Operator):
    ''' An example operator for addon '''
    bl_idname = "render.render_iso"
    bl_label  = "Render ISO"
    bl_options = {'REGISTER'}

    tile_width = bpy.props.IntProperty(
        name="Tile width",
        min=0,
        max=1000
    )

    def execute(self, context):
        obj = context.scene.objects.active
        # Do the rendering here
        return {"FINISHED"}

    def draw(self, context):
        layout = self.layout

class RenderIsoPanel(bpy.types.Panel):
    bl_idname = "RENDER_PT_render_iso"
    bl_label = "Render ISO"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "render"
    bl_options = {'DEFAULT_CLOSED'}


    def draw(self, context):
        layout = self.layout
        layout.operator(RenderIsoOperator.bl_idname)
        # Get the controls here.

def register():
    bpy.utils.register_class(RenderIsoOperator)
    bpy.utils.register_class(RenderIsoPanel)

def unregister():
    bpy.utils.unregister_class(RenderIsoOperator)
    bpy.utils.register_class(RenderIsoPanel)



if __name__ == "__main__":
    register()
$\endgroup$
3
$\begingroup$

Using both a pointer, property group setup. The tile width, scene.iso_render.tile_width, is passed to the operator. You could bypass defining and using the operator property entirely and just use context.scene.iso_render.tile_width (and other settings) directly in the operator.

import bpy
from bpy.props import IntProperty, PointerProperty
from bpy.types import PropertyGroup, Operator, Panel
from bpy.utils import register_class, unregister_class

bl_info = { 
    "name":     "Render ISO", 
    "category": "Render"  # perhaps wrong
}

class RenderIsoOperator(Operator):
    ''' An example operator for addon '''
    bl_idname = "render.render_iso"
    bl_label  = "Render ISO"
    bl_options = {'REGISTER'}

    tile_width = IntProperty(
        name="Tile width",
        min=0,
        max=1000
    )

    def execute(self, context):
        obj = context.scene.objects.active
        # Do the rendering here
        return {"FINISHED"}


class RenderIsoPanel(Panel):
    bl_idname = "RENDER_PT_render_iso"
    bl_label = "Render ISO"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "render"
    bl_options = {'DEFAULT_CLOSED'}

    def draw(self, context):
        scene = context.scene
        layout = self.layout
        op = layout.operator(RenderIsoOperator.bl_idname)
        op.tile_width = scene.iso_render.tile_width
        layout.prop(scene.iso_render, "tile_width")

class IsoRenderSettings(PropertyGroup):
    tile_width = IntProperty(
        name="Tile width",
        min=0,
        max=1000
    )
def register():
    register_class(IsoRenderSettings)

    bpy.types.Scene.iso_render = PointerProperty(type=IsoRenderSettings)
    register_class(RenderIsoOperator)
    register_class(RenderIsoPanel)

def unregister():
    unregister_class(IsoRenderSettings)
    unregister_class(RenderIsoOperator)
    unregister_class(RenderIsoPanel)
    del(bpy.types.Scene.iso_render)

if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ Yes, that's what I actually did, I wanted to avoid writing to the Scene(ID) datablock, but I've found no workaround. Thanks nevertheless, this will certainly stand for some knowledge of the not-so-easy Blender Python API. $\endgroup$ – luke1985 Dec 22 '15 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.