TypeError: คาดว่าประเภท 'Depsgraph' จะพบ 'Scene' แทน

Sep 10 2020

ฉันได้พบสคริปต์ที่ยอดเยี่ยมโดย @Leander เพื่อทำสิ่งที่ฉันพยายามจะบรรลุที่นี่:

https://blender.stackexchange.com/a/109468/30363

ซึ่งมีสองสคริปต์สคริปต์แรกสร้างวัตถุสคริปต์ที่สองใช้วัตถุที่สร้างขึ้นเพื่อขยายตาข่ายจนกว่าจะกระทบกับวัตถุอื่นในฉากจากนั้นจะสร้างวัตถุที่ดูเหมือนการสแกนระนาบเลเซอร์

ฉันได้จัดการเพื่อให้สคริปต์แรกทำงานด้วย blender 2.83.1 โดยการอัปเดตรหัส python โดยใช้สิ่งนี้ https://blenderartists.org/t/2-80-cheat-sheet-for-updating-add-ons/1148974 เป็นแนวทาง

import bpy
import bmesh
from mathutils.bvhtree import BVHTree
import mathutils
import math
import numpy as np

EPSILON = 0.00001
MAXIMUM_DISTANCE = 10

object_name = 'light_plane'
radius_start = math.pi*1/4
radius_end   = math.pi*3/4
radius_step  = math.pi/256

angles = [(math.cos(a), math.sin(a)) for a in np.arange(radius_start, radius_end + 0.00001, radius_step)]

def create_mesh_obj(bm, p_name = "from_bmesh"):
    scn = bpy.context
    me = bpy.data.meshes.new(name = p_name)
    bm.to_mesh(me)

    if (p_name not in bpy.data.objects):
        ob = bpy.data.objects.new(name = p_name, object_data = me)
        scn.collection.objects.link(ob)
    else:
        ob = bpy.data.objects[p_name]
        ob.data = me
    scn.view_layer.update()
    return ob

def create_vertice_shapes(angles):
    bm = bmesh.new()
    for a in angles:
        bm.verts.new((a[0], a[1], 0))
    bm.verts.new((0, 0, 0))
    ob = create_mesh_obj(bm)
    bm.free()
#    basis = ob.shape_key_add(from_mix=False)
#    basis.name = "basis"
    return ob

ob = create_vertice_shapes(angles)
ob.name = object_name

แต่ฉันไม่มีโชคกับสคริปต์ที่สอง

import bpy
import bmesh
from mathutils.bvhtree import BVHTree
import mathutils
import math
import numpy as np

EPSILON = 0.00001
MAXIMUM_DISTANCE = 5

object_name = 'light_plane'
radius_start = math.pi*1/4
radius_end   = math.pi*3/4
radius_step  = math.pi/256


angles = [(math.cos(a), math.sin(a)) for a in np.arange(radius_start, radius_end + 0.00001, radius_step)]
print(angles)

def set_positions(ob, angles, obstacles):
    trees = []
    for obstacle in obstacles:
        bm = bmesh.new()
        bm.from_object(obstacle, bpy.context.scene)
        bmesh.ops.transform(bm, matrix=obstacle.matrix_world, verts=bm.verts)
        trees.append(BVHTree.FromBMesh(bm, epsilon=EPSILON))

    for idx, a in enumerate(angles):
        min_dist = MAXIMUM_DISTANCE
        v_loc = mathutils.Vector((a[0], a[1], 0)) * MAXIMUM_DISTANCE
        for bvh in trees:
            v = (ob.matrix_world * mathutils.Vector((a[0], a[1], 0))) - ob.location
            loc, no, i, d = bvh.ray_cast(ob.location, v)
            if d is not None:
                if d < min_dist:
                    min_dist = d
                    v_loc = ob.matrix_world.inverted() * loc
        ob.data.vertices[idx].co = v_loc


def my_handler(scene):
    ob = bpy.data.objects[object_name]
    selection = [oo for oo in bpy.data.objects if oo != ob]
    print(ob.location)
    set_positions(ob, angles, selection)

for h in bpy.app.handlers.depsgraph_update_pre:
    bpy.app.handlers.scene_update_pre.remove(h)
for h in bpy.app.handlers.frame_change_pre:
    bpy.app.handlers.frame_change_pre.remove(h)
#bpy.app.handlers.scene_update_pre.append(my_handler)
#bpy.app.handlers.frame_change_pre.append(my_handler)
my_handler(bpy.context.scene)

ข้อผิดพลาดที่ฉันได้รับคือ"TypeError: expected" Depsgraph type found "Scene" แทน "ที่ไฮไลต์ในบรรทัดที่ 24

bm.from_object(obstacle, bpy.context.scene) 

ใครสามารถให้ความช่วยเหลือได้บ้าง?

คำตอบ

5 batFINGER Sep 11 2020 at 07:48

การเปลี่ยนแปลง API บางอย่างใหม่กว่าการเปลี่ยนแปลงอื่น ๆ

bmesh จากเมธอดอ็อบเจ็กต์ต้องการอาร์กิวเมนต์ 2 เป็นเดปกราฟไม่ใช่ฉากเนื่องจาก IIRC ก่อนหน้านี้ประมาณเมื่อมีการเขียนคำตอบ

ดูเอกสารล่าสุดเพิ่มเติมอย่างไรก็ตามสำหรับสิ่งนี้ขอแนะนำอย่างยิ่งให้ใช้คุณสมบัติเติมข้อความอัตโนมัติของคอนโซล

>>> bm.from_object(
from_object(object, depsgraph, deform=True, cage=False, face_normals=True)
.. method:: from_object(object, depsgraph, deform=True, cage=False, face_normals=True)
Initialize this bmesh from existing object datablock (currently only meshes are supported).
:arg object: The object data to load.
:type object: :class:`Object`
:arg deform: Apply deformation modifiers.
:type deform: boolean
:arg cage: Get the mesh as a deformed cage.
:type cage: boolean
:arg face_normals: Calculate face normals.
:type face_normals: boolean

จะสังเกตเห็นว่า depsgraph ไม่ได้สร้างสตริง doc ชัดเจนว่ามันเป็นอาร์กิวเมนต์

ทดสอบการทำความสะอาด ได้ทำการเปลี่ยนแปลงเพียงเล็กน้อยเพื่อให้สิ่งนี้ทำงานเป็นตัวจัดการโพสต์การเปลี่ยนเฟรม ใช้ "วงกลม" 256 จุดเป็นวัตถุทดสอบ ( ให้ข้อกำหนดว่าต้องมีจำนวนมุมอย่างน้อยเท่าจำนวนมุม )

สคริปต์แสดงข้อผิดพลาดดัชนีสำหรับเมชที่มีเวอร์น้อยเกินไป ...

วิธีนี้เชื่อมต่อกับตัวจัดการการเปลี่ยนเฟรมดังนั้นมันจะทำ "ของมัน" เมื่อเฟรมกำลังเปลี่ยน

_ ตัวอย่างการย้ายคิวบ์สองสามอันพร้อมกับการเล่นแอนิเมชั่นเพื่อเรียก (จัดการ) ในเหตุการณ์การเปลี่ยนแปลงเฟรมการอัปเดตเมชด้วยโค้ดตัวจัดการ

import bpy
import bmesh
from mathutils.bvhtree import BVHTree
import mathutils
import math
import numpy as np

EPSILON = 0.00001
MAXIMUM_DISTANCE = 5

object_name = 'Circle' # change this to your object name
radius_start = math.pi*1/4
radius_end   = math.pi*3/4
radius_step  = math.pi/256


angles = [(math.cos(a), math.sin(a)) for a in np.arange(radius_start, radius_end + 0.00001, radius_step)]
print(angles)

def set_positions(scene, depsgraph, ob, angles, obstacles):
    trees = []
    for obstacle in obstacles:
        bm = bmesh.new()
        bm.from_object(obstacle, depsgraph)
        bmesh.ops.transform(bm, matrix=obstacle.matrix_world, verts=bm.verts)
        trees.append(BVHTree.FromBMesh(bm, epsilon=EPSILON))

    for idx, a in enumerate(angles):
        min_dist = MAXIMUM_DISTANCE
        v_loc = mathutils.Vector((a[0], a[1], 0)) * MAXIMUM_DISTANCE
        for bvh in trees:
            v = (ob.matrix_world @ mathutils.Vector((a[0], a[1], 0))) - ob.location
            loc, no, i, d = bvh.ray_cast(ob.location, v)
            if d is not None:
                if d < min_dist:
                    min_dist = d
                    v_loc = ob.matrix_world.inverted() @ loc
        ob.data.vertices[idx].co = v_loc


def my_handler(scene, depsgraph):
    ob = scene.objects[object_name]
    selection = [oo for oo in scene.objects if oo != ob and oo.type == 'MESH']
    print(ob.location)
    set_positions(scene, depsgraph, ob, angles, selection)

# to debug n test clear the lot.
bpy.app.handlers.frame_change_post.clear()
bpy.app.handlers.frame_change_post.append(my_handler)

TypeError: การคูณองค์ประกอบอย่างชาญฉลาด: ไม่รองรับระหว่าง 'Matrix' และ 'Vector'

แก้ไข

ดูScan plane "shadow" re my take on an update for 2.8.