1
$\begingroup$

Complete beginner to scripting. I'm trying to create an add-on that would allow me to add a bezier curve with one single control point (vertex) at the 3d cursor.

This is what I have:

bl_info = {
    "name": "Single Point Curve",
    "category": "Object",
}

import bpy

class HalfBoolMirror(bpy.types.Operator):
    """Single Point Curve"""      # blender will use this as a tooltip for menu items and buttons.
    bl_idname = "single.point.curve"        # unique identifier for buttons and menu items to reference.
    bl_label = "Single Point Curve"         # display name in the interface.
    bl_options = {'REGISTER', 'UNDO'}  # enable undo for the operator.

    def execute(self, context):        # execute() is called by blender when running the operator.

        # The original script

        bpy.ops.curve.primitive_bezier_curve_add(view_align=False, enter_editmode=True, location=bpy.context.scene.cursor_location, layers=(True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True))

        bpy.ops.curve.handle_type_set(type='VECTOR')

        bpy.context.object.data.show_handles = False

        bpy.context.object.data.show_normal_face = False

        bpy.ops.curve.de_select_last()

        bpy.ops.curve.delete(type='VERT')

        bpy.ops.curve.select_all(action='TOGGLE')

        for area in bpy.context.screen.areas:
            if area.type == 'VIEW_3D':
                ctx = bpy.context.copy()
                ctx['area'] = area
                ctx['region'] = area.regions[-1]
                bpy.ops.view3d.snap_selected_to_cursor(ctx, use_offset=False)
                break


        return {'FINISHED'}            # this lets blender know the operator finished successfully.

def register():
    bpy.utils.register_class(HalfBoolMirror)


def unregister():
    bpy.utils.unregister_class(HalfBoolMirror)


    if __name__ == "__main__":
    register()

This gives me an error when trying to enable the addon in User Preferences. The error is

line 18 bpy.ops.curve.primitive_bezier_curve_add(view_align=False, enter_editmode=True, location=bpy.context.scene.cursor_location, layers=(True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True)) ^ TabError: inconsistent use of tabs and spaces in indentation

At some point I also got an error saying "incorrect location" or something at line 18. Unable to reproduce it now...

The script works as intended when running it in the script editor such as this:

import bpy

bpy.ops.curve.primitive_bezier_curve_add(view_align=False, enter_editmode=True, location=bpy.context.scene.cursor_location, layers=(True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True))

bpy.ops.curve.handle_type_set(type='VECTOR')
bpy.context.object.data.show_handles = False
bpy.context.object.data.show_normal_face = False
bpy.ops.curve.de_select_last()
bpy.ops.curve.delete(type='VERT')
bpy.ops.curve.select_all(action='TOGGLE')
for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        ctx = bpy.context.copy()
        ctx['area'] = area
        ctx['region'] = area.regions[-1]
        bpy.ops.view3d.snap_selected_to_cursor(ctx, use_offset=False)
        break

But I can't get it to work as an Addon.

$\endgroup$
  • $\begingroup$ The error is about the whitespace in your script, check that you have each line use the same indentation. It is better to not use operators within your own operator, have a look at this answer for an example of another way to do it. $\endgroup$ – sambler Jun 15 '17 at 6:25
1
$\begingroup$

Trying to run it here I got a bad identation error on line 52 in register().

Fixing that I could install the addon, then it complained about

Traceback (most recent call last):
  File "D:\Duarte\System\Blender\2.78\scripts\modules\addon_utils.py", line 349, in enable
    mod.register()
  File "D:\Duarte\System\Blender\2.78\scripts\addons\SinglePointCurve.py", line 44, in register
    bpy.utils.register_class(HalfBoolMirror)
RuntimeError: Error: Registering operator class: 'HalfBoolMirror', invalid bl_idname 'single.point.curve', must contain 1 '.' character

Apparently your bl_idname = "single.point.curve" on line 10 can only have one one "." period character in its name.

Changing it to bl_idname = "singlepoint.curve" seemd to fix the problem and the script installed fine, though I could not see it anywhere in the UI.

This is my final result

bl_info = {
    "name": "Single Point Curve",
    "category": "Object",
}

import bpy

class HalfBoolMirror(bpy.types.Operator):
    """Single Point Curve"""      # blender will use this as a tooltip for menu items and buttons.
    bl_idname = "singlepoint.curve"        # unique identifier for buttons and menu items to reference.
    bl_label = "Single Point Curve"         # display name in the interface.
    bl_options = {'REGISTER', 'UNDO'}  # enable undo for the operator.

    def execute(self, context):        # execute() is called by blender when running the operator.

        # The original script

        bpy.ops.curve.primitive_bezier_curve_add(view_align=False, enter_editmode=True, location=bpy.context.scene.cursor_location, layers=(True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True))

        bpy.ops.curve.handle_type_set(type='VECTOR')

        bpy.context.object.data.show_handles = False

        bpy.context.object.data.show_normal_face = False

        bpy.ops.curve.de_select_last()

        bpy.ops.curve.delete(type='VERT')

        bpy.ops.curve.select_all(action='TOGGLE')

        for area in bpy.context.screen.areas:
            if area.type == 'VIEW_3D':
                ctx = bpy.context.copy()
                ctx['area'] = area
                ctx['region'] = area.regions[-1]
                bpy.ops.view3d.snap_selected_to_cursor(ctx, use_offset=False)
                break


        return {'FINISHED'}            # this lets blender know the operator finished successfully.

def register():
    bpy.utils.register_class(HalfBoolMirror)


def unregister():
    bpy.utils.unregister_class(HalfBoolMirror)


if __name__ == "__main__":
    register()
$\endgroup$
  • 1
    $\begingroup$ If you also remove the extra indentation for the if __name__ and the following line then running it in the script editor will register the operator. $\endgroup$ – sambler Jun 15 '17 at 6:21

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.