0
$\begingroup$

if I want these classes to be called by other plugins, like Pie Menu Editor addon, What code should I add?

enter image description here

import bpy

class Cam_Base(bpy.types.Operator):
    bl_idname = "cam.base"
    bl_label = "Cam Base"
    cam_name = "C_"
    
    def execute(self, context):
        C = bpy.context

        # lock cam
        bpy.context.object.lock_scale = (True, True, True)
        bpy.context.object.lock_rotation = (True, True, True)
        bpy.context.object.lock_location = (True, True, True)

        # select cam
        bpy.context.space_data.camera = bpy.data.objects[self.cam_name]

        # Select Active Cam
        for area in C.screen.areas:
            if area.type == 'VIEW_3D':
                A = C.area.spaces.active.camera

        bpy.context.scene.camera = bpy.data.objects[A.name]

        bpy.context.space_data.shading.color_type = 'OBJECT'
        bpy.context.space_data.region_3d.view_perspective = 'CAMERA'
#############Supplementary Code################
        #Modify camera attributes
        bpy.data.objects[A.name].lock_scale[0] = True
        bpy.data.objects[A.name].lock_scale[1] = True
        bpy.data.objects[A.name].lock_scale[2] = True
        bpy.data.objects[A.name].lock_location[0] = True
        bpy.data.objects[A.name].lock_location[1] = True
        bpy.data.objects[A.name].lock_location[2] = True
        bpy.data.objects[A.name].lock_rotation[0] = True
        bpy.data.objects[A.name].lock_rotation[1] = True
        bpy.data.objects[A.name].lock_rotation[2] = True
        bpy.data.objects[A.name].scale[0] = 1
        bpy.data.objects[A.name].scale[1] = 1
        bpy.data.objects[A.name].scale[2] = 1
        bpy.data.cameras[A.name].display_size = 0.05
        bpy.data.cameras[A.name].background_images[0].alpha = 0
        bpy.data.cameras[A.name].dof.use_dof = False
        bpy.data.cameras[A.name].clip_start = 25
        bpy.data.cameras[A.name].clip_end = 100000
        bpy.data.cameras[A.name].background_images[0].scale = 1
        bpy.data.cameras[A.name].background_images[1].scale = 1
        bpy.data.cameras[A.name].background_images[2].scale = 1

        bpy.ops.view3d.view_center_camera()
        bpy.ops.image.reload()
    
        #select camera as active objcet in object mode
        if bpy.context.object.mode == 'OBJECT':
            bpy.ops.object.select_all(action='DESELECT')
            objectToSelect = bpy.data.objects[A.name]
            objectToSelect.select_set(True)
            bpy.context.view_layer.objects.active = objectToSelect
#############Supplementary Code################
        return {'FINISHED'}

class Cam_0V0(Cam_Base):
    bl_idname = "cam.0v0"
    bl_label = "Cam_0V0"
    cam_name = "C_0V0"

class Cam_0V1(Cam_Base):
    bl_idname = "cam.0v1"
    bl_label = "Cam_0V1"
    cam_name = "C_0V1"

class Cam_0V2(Cam_Base):
    bl_idname = "cam.0v2"
    bl_label = "Cam_0V2"
    cam_name = "C_0V2"

addon_keymaps = []

def register():
    bpy.utils.register_class(Cam_Base)
    bpy.utils.register_class(Cam_0V0)
    bpy.utils.register_class(Cam_0V1)
    bpy.utils.register_class(Cam_0V2)

def unregister():
    bpy.utils.unregister_class(Cam_Base)
    bpy.utils.unregister_class(Cam_0V0)
    bpy.utils.unregister_class(Cam_0V1)
    bpy.utils.unregister_class(Cam_0V2)

if __name__ == "__main__":
    register()
$\endgroup$
3
  • $\begingroup$ AFAIK it won't work if you use inheritance in that way. An operator class must inherit directly from bpy.types.Operator to correctly register. It's a quirk of the API. You can use composition though, and inherit from Operator and another class $\endgroup$
    – Gorgious
    Commented Apr 20, 2023 at 6:22
  • $\begingroup$ So how do I change the code? $\endgroup$
    – lee blues
    Commented Apr 20, 2023 at 7:34
  • $\begingroup$ make Cam_Base a base class (no inheritance) and define your child classes with Cam_0V0(Cam_Base, bpy.types.Operator):. Note that you won't be able to register Cam_Base $\endgroup$
    – Gorgious
    Commented Apr 20, 2023 at 7:37

1 Answer 1

0
$\begingroup$

You need to use context overrides. In this example, I added your operator buttons into the header of the Python Console:

import bpy

class Cam_Base():
    bl_idname = "cam.base"
    bl_label = "Cam Base"
    cam_name = "C_"

    def execute(self, context):
        area_type = 'VIEW_3D'
        areas = [area for area in bpy.context.window.screen.areas if area.type == area_type]

        if len(areas) <= 0:
            raise Exception(f"Make sure an Area of type {area_type} is open or visible in your screen!")

        with bpy.context.temp_override(area=areas[0]):        
            c = bpy.context
            c.object.lock_scale = (True, True, True)
            c.object.lock_rotation = (True, True, True)
            c.object.lock_location = (True, True, True)
            c.space_data.camera = bpy.data.objects[self.cam_name]
            c.scene.camera = bpy.data.objects[self.cam_name]

        return {'FINISHED'}


class Cam_0V0(bpy.types.Operator, Cam_Base):
    bl_idname = "cam.cam0"
    bl_label = "Cam_0V0"
    cam_name = "C_0V0"


class Cam_0V1(bpy.types.Operator, Cam_Base):
    bl_idname = "cam.cam1"
    bl_label = "Cam_0V1"
    cam_name = "C_0V1"


class Cam_0V2(bpy.types.Operator, Cam_Base):
    bl_idname = "cam.cam2"
    bl_label = "Cam_0V2"
    cam_name = "C_0V2"


class Info_Head(bpy.types.Header):
    bl_space_type = 'INFO'

    def draw(self, context):
        self.layout.operator("cam.cam0")
        self.layout.operator("cam.cam1")
        self.layout.operator("cam.cam2")

    bpy.types.CONSOLE_HT_header.prepend(draw)


addon_keymaps = []

def register():
    bpy.utils.register_class(Cam_0V0)
    bpy.utils.register_class(Cam_0V1)
    bpy.utils.register_class(Cam_0V2)

def unregister():
    bpy.utils.unregister_class(Cam_0V0)
    bpy.utils.unregister_class(Cam_0V1)
    bpy.utils.unregister_class(Cam_0V2)
    
if __name__ == "__main__":
    register()
$\endgroup$
8
  • 1
    $\begingroup$ You are wonderful! But I missed a piece of code before, how to add this piece of code to the new code, can you help me to simplify and standardize this code, the new code is in between #Supplementary Code# and #Supplementary Code# I tried it myself to add but it reported an error, so I'll have to ask you $\endgroup$
    – lee blues
    Commented Apr 20, 2023 at 9:59
  • $\begingroup$ ah just nest the supplementary code after with bpy.context.temp_override similar to my answer $\endgroup$
    – Harry McKenzie
    Commented Apr 20, 2023 at 10:22
  • $\begingroup$ All other code is normal, but this is the only one that reports an error ”bpy.ops.view3d.view_center_camera()” ----RuntimeError:Operator bpy.ops.view3d.view center camera.poll()failed,context is incorrect . How do I go about modifying it? $\endgroup$
    – lee blues
    Commented Apr 20, 2023 at 10:52
  • $\begingroup$ bpy.ops.view3d.view_center_camera() should also work within the VIEW_3D context. can u edit your question and add an updated version of your code $\endgroup$
    – Harry McKenzie
    Commented Apr 20, 2023 at 11:24
  • $\begingroup$ I was thinking the same thing, but there was an error. Here is the full code of the error. Python:Traceback (most recent call last): File "C:\Users\blues\AppData\RoamingBlender Foundation\Blender3.3\scripts\addons\CamS3.py",line 49,in execute bpy.ops.view3d.view_center_camera() File "C:\Programs\blender-3.3.0-windows-x6413.3\scripts\modules\bpyops.py".line 113,in call ret op call(self.idname_py(),None,kw) RuntimeError:Operator bpy.ops.view3d.view_center_camera.poll()failed,context is incorrect $\endgroup$
    – lee blues
    Commented Apr 20, 2023 at 12:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .