4
$\begingroup$

I'm writing a script, where an operator is registered in the Add->Mesh menu. Clicking this menu displays a panel, where the user can enter certain parameters and then invoke another operator using a button in the panel.

I'm using custom scene properties for the parameters, as shown in this code snippet.

The text property is set to an empty string whenever I edit it. It starts out with the default value "Lorem ipsum". Whenever I change the value in the panel text box, and then click away, the text box loses its value.

Here's my stripped down code, which still doesn't work:

def initSceneProperties(scene):
    bpy.types.Scene.photoPath = StringProperty(
            name="Path to photos",
            description="Path to the folder containing the JPG photos")
    scene["photoPath"] = "Lorem ipsum"
    return

initSceneProperties(bpy.context.scene)
# ==============================================================
class add_mesh_point_cloud(bpy.types.Operator):
    bl_idname = "mesh.point_cloud_add"
    bl_label = "Add Point Cloud"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = "Generate a point cloud from photographs"

    def execute(self, context):
        return {'FINISHED'}

    def invoke(self, context, event):
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout
        layout.prop(context.scene, "photoPath")

What's happening? How can I fix it?

$\endgroup$
4
$\begingroup$

If you use the operator panel in the toolbar with register, changing a value in the panel will undo the changes made by the last call of the operator's execute method (including the change made to the scene's custom property which causes the update procedure and then gets reset to its previous value when the undo is performed) and run the method again with the new parameters given.

You could simply use another string property for the operator and assign it's value to scene.photoPath in the operator's execute method.

import bpy

class add_mesh_point_cloud(bpy.types.Operator):
    bl_idname = "mesh.point_cloud_add"
    bl_label = "Add Point Cloud"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = "Generate a point cloud from photographs"

    photoPath = bpy.props.StringProperty(
                    name="Path to photos",
                    description="Path to the folder containing the JPG photos"
                    )

    def execute(self, context):
        context.scene.photoPath = self.photoPath
        return {'FINISHED'}

    def invoke(self, context, event):
        self.photoPath = context.scene.photoPath
        return self.execute(context)

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "photoPath")

if __name__ == "__main__":
    bpy.utils.register_class(add_mesh_point_cloud)
    bpy.types.Scene.photoPath = bpy.props.StringProperty(
                                    default = "LoremIpsum"
                                    )
$\endgroup$
  • $\begingroup$ That worked like a charm. Thanks for the concise explanation and corrected code. One clarification for future readers: I had to declare the photoPath variable in the scene using bpy.types.Scene.photoPath = StringProperty(...) (not shown in the answer). $\endgroup$ – ApoorvaJ Mar 2 '14 at 12:15

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.