跳转到内容

Blender 3D:菜鸟到高手/高级教程/Blender 脚本/添加自定义属性

来自维基教科书,开放的书籍,开放的世界

插件通常会做更多的事情,而不仅仅是无条件地执行单个操作;用户可以通过多种方式控制它们的操作。我们可以为插件面板添加用于调整设置的控件,并将这些控件与为当前场景定义的自定义属性关联起来;Blender 随后会负责在用户操作这些控件时更新属性值,而我们的运算符的调用例程可以在运行时获取这些属性值。

定义属性

[编辑 | 编辑源代码]

属性需要在自定义类注册时同时定义。我们之前在顶层语句中完成此操作,但现在让我们将所有内容一起收集到一个注册方法中,如下所示

def register() :
    bpy.utils.register_class(MakeTetrahedron)
    bpy.utils.register_class(TetrahedronMakerPanel)
    bpy.types.Scene.make_tetrahedron_inverted = bpy.props.BoolProperty \
      (
        name = "Upside Down",
        description = "Generate the tetrahedron upside down",
        default = False
      )
#end register

在这里,我们将属性作为 Blender 的新属性附加场景类;Python 允许我们将新属性分配给几乎任何对象,Blender 充分利用了这一点。请注意,必须使用bpy.props中提供的属性定义例程之一来创建属性;选择与您要创建的属性类型匹配的例程。在这里,我们定义了一个简单的真/假切换,用户将通过复选框控制它。无论您为自定义类属性使用什么名称,该类的实例都将具有相同名称的属性,该属性保存该属性的实际值。

名称将用作用于检查或更改此属性的控件的名称,而描述将作为工具提示出现在用户将鼠标悬停在控件上时。这默认值用作属性的初始值。

还要注意,我尝试使用一个名称,make_tetrahedron_inverted,该名称不太可能与其他插件或 Blender 部分定义的名称冲突。

我们还将添加一个注销方法,它撤消注册所做的一切。这目前不会真正使用,但当我们提取插件以进行单独安装时,它将变得相关

def unregister() :
    bpy.utils.unregister_class(MakeTetrahedron)
    bpy.utils.unregister_class(TetrahedronMakerPanel)
    del bpy.types.Scene.make_tetrahedron_inverted
#end unregister

要使复选框显示,请将以下行添加到面板的绘制例程

       TheColumn.prop(context.scene, "make_tetrahedron_inverted")

prop方法的第一个参数必须是我们在上面附加属性定义的类的实例;在本例中,它是当前场景。

最后,我们需要用以下样板代码完成我们的脚本,该代码将在 Blender 不为我们调用注册例程的情况下(例如在文本编辑器中)调用该例程

if __name__ == "__main__" :
    register()
#end if

使用属性

[编辑 | 编辑源代码]

现在,我们需要在运算符的执行例程中实际使用该属性。我们将使用它来否定应用于四面体顶点 Z 坐标的比例因子

        Scale = -1 if context.scene.make_tetrahedron_inverted else 1

但只有最后一个顶点具有非零 Z 坐标,因此这是唯一需要更改其计算的顶点

        Vertices = \
          [
            mathutils.Vector((0, -1 / math.sqrt(3),0)),
            mathutils.Vector((0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((-0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((0, 0, Scale * math.sqrt(2 / 3))),
          ]

整合在一起

[编辑 | 编辑源代码]

为了回顾我们所有更改,以下是完整的更新脚本

import math
import bpy
import mathutils

class TetrahedronMakerPanel(bpy.types.Panel) :
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_context = "objectmode"
    bl_category = "Create"
    bl_label = "Add Tetrahedron"

    def draw(self, context) :
        TheColumn = self.layout.column(align = True)
        TheColumn.prop(context.scene, "make_tetrahedron_inverted")
        TheColumn.operator("mesh.make_tetrahedron", text = "Add Tetrahedron")
    #end draw

#end TetrahedronMakerPanel

class MakeTetrahedron(bpy.types.Operator) :
    bl_idname = "mesh.make_tetrahedron"
    bl_label = "Add Tetrahedron"
    bl_options = {"UNDO"}

    def invoke(self, context, event) :
        Scale = -1 if context.scene.make_tetrahedron_inverted else 1
        Vertices = \
          [
            mathutils.Vector((0, -1 / math.sqrt(3),0)),
            mathutils.Vector((0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((-0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((0, 0, Scale * math.sqrt(2 / 3))),
          ]
        NewMesh = bpy.data.meshes.new("Tetrahedron")
        NewMesh.from_pydata \
          (
            Vertices,
            [],
            [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
          )
        NewMesh.update()
        NewObj = bpy.data.objects.new("Tetrahedron", NewMesh)
        context.scene.objects.link(NewObj)
        return {"FINISHED"}
    #end invoke

#end MakeTetrahedron

def register() :
    bpy.utils.register_class(MakeTetrahedron)
    bpy.utils.register_class(TetrahedronMakerPanel)
    bpy.types.Scene.make_tetrahedron_inverted = bpy.props.BoolProperty \
      (
        name = "Upside Down",
        description = "Generate the tetrahedron upside down",
        default = False
      )
#end register

def unregister() :
    bpy.utils.unregister_class(MakeTetrahedron)
    bpy.utils.unregister_class(TetrahedronMakerPanel)
    del bpy.types.Scene.make_tetrahedron_inverted
#end unregister

if __name__ == "__main__" :
    register()
#end if

与之前一样,使用  ALT + P  执行脚本。检查 3D 视图中的工具架,您的面板现在应该看起来像这样

尝试在选中和未选中复选框的情况下执行它,您应该得到两个朝相反方向指向的四面体。

华夏公益教科书