欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python可擴(kuò)展的Blender 3D插件開(kāi)發(fā)匯總

 更新時(shí)間:2023年09月04日 09:19:25   作者:xiangzhihong  
這篇文章主要為大家介紹了python可擴(kuò)展的Blender 3D插件開(kāi)發(fā)匯總,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Blender 3D 插件

成熟的 Blender 3D 插件是令人驚奇的事情。作為 Python 和 Blender 的新手,我經(jīng)常發(fā)現(xiàn)自己被社區(qū)中的人們創(chuàng)造的強(qiáng)大的東西弄得目瞪口呆。坦率地說(shuō),其中一些包看起來(lái)有點(diǎn)神奇,當(dāng)自我懷疑或冒名頂替綜合癥的嘮叨聲音被打破時(shí),很容易想到“如果有人能做出可以做xxx的東西就好了” 。

然后我記得,通過(guò)將好奇心和固執(zhí)與良好的文檔相結(jié)合,某人可以是任何人,X可以成為X、Y 和 Z。即使是困難的部分也可以弄清楚——尤其是因?yàn)樗泄虉?zhí)和好奇的人確保 Blender 的 Python文檔和stackexchange與它讓我們創(chuàng)建的 gee whiz 圖形一樣好。

同樣的方式,已經(jīng)存在的文檔和模型為從頭開(kāi)始編寫(xiě) Blender 插件奠定了平滑的基礎(chǔ),在開(kāi)始時(shí)為該插件提供可擴(kuò)展的結(jié)構(gòu)有助于展示 Python API 的各個(gè)部分如何更多地組合在一起清楚地。換句話(huà)說(shuō),它使新編寫(xiě)的代碼比原來(lái)更好,同時(shí)也使現(xiàn)有代碼更容易學(xué)習(xí)。

在本文的最后,我們將創(chuàng)建一個(gè)功能齊全且已安裝的插件,它提供了一個(gè)自定義 UI 元素來(lái)將Standoff 添加到 Blender 場(chǎng)景中,并帶有界面控件來(lái)調(diào)整創(chuàng)建的網(wǎng)格的直徑和高度。

一、文件結(jié)構(gòu)

本文末尾將存在的完整目錄和文件結(jié)構(gòu),我們可以使用mkdir和touch方式進(jìn)行創(chuàng)建,本示例是一個(gè)填空游戲。我正在調(diào)用項(xiàng)目DemoRack并將其設(shè)置為我用于 Python 項(xiàng)目的文件夾中的頂級(jí)目錄名稱(chēng):它不一定必須是 Blender 特定的任何地方。下面是DemoRack項(xiàng)目的文件結(jié)構(gòu):

DemoRack
|-- README.md 
|-- DemoRack.zip <-- will (re)compile via 'zip -r DemoRack.zip src'
|-- src
|-- |-- __init__.py
|-- |-- standoff_mesh.py <-- from Part 2, not modified in this post 
|-- |-- standoff_operator.py
|-- |-- standoff_panel.py
|-- |-- standoff_props.py

下面我們簡(jiǎn)單介紹下這些文件的作用:

  • DemoRack.zip:已編譯src,安裝在 Blender 中的文件。
  • __init__.py:為附加組件注冊(cè)所有必要的信息和類(lèi)。
  • standoff_mesh.py:用于生成目標(biāo)幾何/網(wǎng)格數(shù)據(jù)的模塊。
  • standoff_operator.py:將提供給 UI 使用的“do-er”。
  • standoff_panel.py:在 UI 元素上添加插件將......添加。
  • standoff_props.py:定義Panel 和 Operator所需的數(shù)據(jù)對(duì)象

簡(jiǎn)而言之,每個(gè)新standoff_模塊都將包含register()和unregister()函數(shù)。該__init__模塊將導(dǎo)入這些模塊,并將兩種類(lèi)型的函數(shù)捆綁到單個(gè)迭代器中。Blender Python 文檔描述了這些函數(shù)所扮演的角色:

二、__init__.py

有了這個(gè)背景,并且因?yàn)開(kāi)_init__模塊中的大部分代碼都與sys和importlib包有關(guān),所以我將在此處包含要點(diǎn),而不會(huì)試圖去描述 Python 模塊導(dǎo)入的雜草。Blender插件需要注意的具體事項(xiàng)是module_names列表,聲明要引入register和unregister函數(shù)的的文件名,以及打開(kāi)的bl_info字典。如官方插件介紹教程中所述,bl_info包含將在“首選項(xiàng)”窗格中找到的所有信息:

bl_info是包含附加元數(shù)據(jù)的字典,例如要顯示在首選項(xiàng)附加列表中的標(biāo)題、版本和作者。它還指定了運(yùn)行腳本所需的最低 Blender 版本;舊版本不會(huì)在列表中顯示加載項(xiàng)。 

下面是一段示例代碼:

bl_info = {
    "name": "DemoRack",
    "description": "Make Mini Rack Units Dynamically",
    "author": "Jim O'Connor <hello@ocommaj.com>",
    "version": (0, 0, 1),
    "blender": (2, 90, 1),
    "category": "3D View"
}
module_names = [ 'standoff_props', 'standoff_operator', 'standoff_panel' ]
import sys
import importlib
module_full_names = [ f"{__name__}.{module}" for module in module_names ]
for module in module_full_names:
    if module in sys.modules:
        importlib.reload(sys.modules[module])
    else:
        locals()[module] = importlib.import_module(module)
        setattr(locals()[module], 'module_names', module_full_names)
def register():
    for module in module_full_names:
        if module in sys.modules:
            if hasattr(sys.modules[module], 'register'):
                sys.modules[module].register()
def unregister():
    for module in module_full_names:
        if module in sys.modules:
            if hasattr(sys.modules[module], 'unregister'):
                sys.modules[module].unregister()

三、standoff_props.py

該模塊將是其中涉及最多的模塊,但它也為其他模塊提供了主干,并實(shí)現(xiàn)了一種可以廣泛重用的模式。它依賴(lài)于導(dǎo)入用于將一組屬性定義捆綁在一起的PropertyGroup類(lèi)型(文檔),bpy.props。一旦PropertyGroup在 Blender 中注冊(cè),它就在 Python 可腳本化數(shù)據(jù)對(duì)象的指針和底層 C 分配的內(nèi)存之間提供了一座橋梁,這些內(nèi)存完成了 Blender 的繁重工作。

我們需要在standoff_props.py類(lèi)中將定義、繼承bpy.types.PropertyGroup并跟蹤 3 個(gè)屬性:

  • metric_diameter: FloatProperty(**kwargs)
  • height: FloatProperty(**kwargs)
  • mesh: PointerProperty(type=Mesh)

其中,前兩個(gè)應(yīng)該是不言自明的,并且在實(shí)現(xiàn)中將有更多關(guān)于參數(shù)的細(xì)節(jié)。第3個(gè)PointerProperty指向內(nèi)存中的一個(gè)對(duì)象,并要求在定義時(shí)指定該對(duì)象的類(lèi)型,并且它是 PropertyGroup的子類(lèi)或bpy.struct.ID(即 Mesh)。這意味著任何將值設(shè)置為任何其他數(shù)據(jù)類(lèi)型的實(shí)例的嘗試(在這種情況下,任何非 bpy.types.Mesh)都將引發(fā)錯(cuò)誤,任何將值傳遞給期望任何其他數(shù)據(jù)的參數(shù)的嘗試也是如此類(lèi)型。

在這種情況下,mesh的 PointerProperty屬性將用于保存在Standoff.mesh()的返回值,并使用存儲(chǔ)在metric_diameter和height后面的值進(jìn)行實(shí)例化和修改。這三個(gè)屬性的完整定義如下所示:

class PG_Standoff(PropertyGroup):
    metric_diameter: FloatProperty(
        name="Inner Diameter (Metric)",
        min=2,
        max=5,
        step=50,
        precision=1,
        set=prop_methods("SET", "metric_diameter"),
        get=prop_methods("GET", "metric_diameter"),
        update=prop_methods("UPDATE"))
    height: FloatProperty(
        name="Standoff Height",
        min=2,
        max=6,
        step=25,
        precision=2,
        set=prop_methods("SET", "height"),
        get=prop_methods("GET", "height"),
        update=prop_methods("UPDATE"))
    mesh: PointerProperty(type=Mesh)
    

單獨(dú)的set 、 get和update參數(shù)都指向prop_methods函數(shù)的返回值。這些值必須是函數(shù),參數(shù)分別為(self, value)、(self)和(self, context)。這個(gè)閉包工廠可能看起來(lái)額外復(fù)雜,但它會(huì)顯著減少重復(fù),并為與PropertyGroup 的數(shù)據(jù)屬性交互提供更大的靈活性。

要理解的一個(gè)重要區(qū)別是,每當(dāng)屬性更改時(shí)都會(huì)調(diào)用update函數(shù)——它不是作為更新定義其屬性的一種方式來(lái)調(diào)用的。相反,它提供了一種將特定屬性的更改傳達(dá)給程序的其他部分的方法;這必須小心使用以避免副作用,并且因?yàn)闆](méi)有檢查來(lái)避免無(wú)限遞歸。

另一件需要注意的是,使用set和get函數(shù)意味著任何default值都必須通過(guò)顯式set調(diào)用(而不是  kwarg)來(lái)設(shè)置,但這也提供了在必要時(shí)掛鉤on_load方法的機(jī)會(huì)。最后,prop_methods函數(shù)必須在調(diào)用它的任何PropertyGroup類(lèi)之前定義。

prop_methods函數(shù)的骨架代碼如下所示:

def prop_methods(call, prop=None):
    def getter(self):
        # getter function must check if prop attr has a value yet
            # if no value, will throw error, so must set default
            # can hook on load here
        # and either way, return self[prop] value
    def setter(self, value):
        self[prop] = value
    def updater(self, context):
        self.update(context)
    methods = {
        "GET": getter,
        "SET": setter,
        "UPDATE": updater
        }
    return methods[call]

完整的實(shí)現(xiàn)如下所示:

def prop_methods(call, prop=None):
    def getter(self):
        try:
            value = self[prop]
        except:
            set_default = prop_methods("SET", prop)
            set_default(self, self.defaults[prop])
            if hasattr(self, "on_load"):
                self.on_load()
            value = self[prop]
        finally:
            return value
    def setter(self, value):
        self[prop] = value
            
    def updater(self, context):
        self.update(context)
    methods = {
        "GET": getter,
        "SET": setter,
        "UPDATE": updater,
        }
    return methods[call]

為此,任何具有調(diào)用prop_methods屬性的類(lèi)都需要一個(gè)名為defaults的字典對(duì)象和一個(gè)名為update的方法(該函數(shù)提供,但不需要on_load方法)。在PG_Standoff類(lèi)中,這些調(diào)用將用于附加Standoff.mesh()的返回值,以及無(wú)論何時(shí)修改metric_diameter或height屬性。PG_Standoff課程的其余部分可以寫(xiě)成:

class PG_Standoff(PropertyGroup):
    # ...
    defaults = { "metric_diameter": 2.5, "height": 3 }
    standoff = Standoff()
    def on_load(self):
        if self.height and self.metric_diameter:
            self.__set_mesh()
    def update(self, context):
        self.__set_mesh()
    def __set_mesh(self):
        self.mesh = self.standoff.mesh(
           self.height, self.metric_diameter)

僅留下import語(yǔ)句和register 、unregister函數(shù)。在 register 函數(shù)中,我們還將從 ointerProperty的實(shí)例中指向PG_PropertyGroup類(lèi),從 Blender 的Scene類(lèi)型的新屬性中引用,這將使從插件的其余部分訪(fǎng)問(wèn)變得簡(jiǎn)單。這將產(chǎn)生一個(gè)完整的standoff_props.py模塊,如下面的要點(diǎn)所示:

from bpy.props import PointerProperty, FloatProperty
from bpy.types import Mesh, PropertyGroup, Scene
from bpy.utils import register_class, unregister_class
from .standoff_mesh import Standoff
def prop_methods(call, prop=None):
    def getter(self):
        try:
            value = self[prop]
        except:
            set_default = prop_methods("SET", prop)
            set_default(self, self.defaults[prop])
            if hasattr(self, "on_load"):
                self.on_load()
            value = self[prop]
        finally:
            return value
    def setter(self, value):
        self[prop] = value
    def updater(self, context):
        self.update(context)
    methods = {
        "GET": getter,
        "SET": setter,
        "UPDATE": updater,
        }
    return methods[call]
class PG_Standoff(PropertyGroup):
    metric_diameter: FloatProperty(
        name="Inner Diameter (Metric)",
        min=2,
        max=5,
        step=50,
        precision=1,
        set=prop_methods("SET", "metric_diameter"),
        get=prop_methods("GET", "metric_diameter"),
        update=prop_methods("UPDATE"))
    height: FloatProperty(
        name="Standoff Height",
        min=2,
        max=6,
        step=25,
        precision=2,
        set=prop_methods("SET", "height"),
        get=prop_methods("GET", "height"),
        update=prop_methods("UPDATE"))
    mesh: PointerProperty(type=Mesh)
    defaults = { "metric_diameter": 2.5, "height": 3 }
    standoff = Standoff()
    def on_load(self):
        if self.height and self.metric_diameter:
            self.__set_mesh()
    def update(self, context):
        self.__set_mesh()
    def __set_mesh(self):
        self.mesh = self.standoff.mesh(self.height, self.metric_diameter)
def register():
    register_class(PG_Standoff)
    Scene.Standoff = PointerProperty(type=PG_Standoff)
def unregister():
    unregister_class(PG_Standoff)
    del Scene.Standoff

四、standoff_operator.py

最后兩個(gè)模塊都是短文件,實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,因?yàn)榻Y(jié)構(gòu)化和修改數(shù)據(jù)的繁重工作已經(jīng)以簡(jiǎn)化其與 Blender Python API 交互的方式完成。在standoff_operator模塊中,我們將定義(并注冊(cè))一個(gè)新bpy.types.Operator類(lèi),然后可以將其附加到任何 UI 按鈕。

如何定義一個(gè)新的Operator有一些要求,但這些都是有據(jù)可查且簡(jiǎn)單明了的,并且通過(guò)從 CLI 啟動(dòng) Blender,警告和錯(cuò)誤消息將立即顯現(xiàn)錯(cuò)誤配置的Operator類(lèi)有。手冊(cè)部分給出了新Operators的預(yù)期定義的詳細(xì)信息。下面腳本將定義docstring、bl_idname、bl_label和bl_options屬性的值。它還將定義一個(gè)execute方法,該方法需要self和context參數(shù),并包含將附加到任何 UI 按鈕調(diào)用注冊(cè)bl_idname 名下的Operator邏輯和事件。

import bpy
from bpy.types import Operator
from bpy.utils import register_class, unregister_class
class DEMORACK_OT_AddNewStandoff(Operator):
    """adds standoff to test add-on registered ok"""
    bl_idname = 'scene.add_new_standoff'
    bl_label = 'New Standoff'
    bl_options = { "REGISTER", "UNDO" }
    def execute(self, context):
        name = "Standoff"
        standoff = context.scene.Standoff # <- set in standoff_props.register()
        collection = context.scene.collection
        obj = bpy.data.objects.new(name, standoff.mesh)
        collection.objects.link(obj)
        obj.select_set(True)
        context.view_layer.objects.active = obj
        return { "FINISHED" }
def register():
    register_class(DEMORACK_OT_AddNewStandoff)
def unregister():
    unregister_class(DEMORACK_OT_AddNewStandoff)

五、standoff_panel.py

定義一個(gè)新Panel類(lèi)幾乎遵循與定義一個(gè)新Operator類(lèi)相同的模式,并且從概念上講,只需將execute最后一步中的draw方法換成這一步中的方法。相關(guān)的Panel 手冊(cè)部分提供了幾個(gè)有用的示例, UI 腳本 > 模板 > Python 菜單中包含更多示例。 在手冊(cè)bpy.types.UILayout部分中可以發(fā)現(xiàn)了更多可能性,該部分記錄了Panel對(duì)象的導(dǎo)入項(xiàng)。在draw方法中,它是一個(gè)簡(jiǎn)單(且非常開(kāi)放)的過(guò)程:

  • 訪(fǎng)問(wèn)context 中的相關(guān)數(shù)據(jù)對(duì)象
  • 為需要按鈕的任何Operator 調(diào)用創(chuàng)建layout.operator對(duì)象
  • 為用戶(hù)可寫(xiě)數(shù)據(jù)屬性創(chuàng)建layout.prop對(duì)象

當(dāng)然,在該模式以及更復(fù)雜的數(shù)據(jù)類(lèi)型中,還有很多擴(kuò)展和變化的空間。但在基礎(chǔ)上,這是另一個(gè)由 API 處理繁重工作的地方,并遵循bpy.props和bpy.types.PropertyGroup實(shí)例的內(nèi)置使用模式。由于這種簡(jiǎn)單性,這是另一個(gè)模塊,它足夠簡(jiǎn)單:

from bpy.types import Panel
from bpy.utils import register_class, unregister_class
class DemoRackPanel:
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "DemoRack"
class StandoffPanel(DemoRackPanel, Panel):
    bl_idname = "DEMORACK_PT_standoff_panel"
    bl_label = "Standoff"
    def draw(self, context):
        layout = self.layout
        standoff_data = context.scene.Standoff # <- set in standoff_props.register()
        layout.operator("scene.add_new_standoff") # <- registered in standoff_operator.py
        layout.prop(standoff_data, "metric_diameter")
        layout.prop(standoff_data, "height")
def register():
    register_class(StandoffPanel)
def unregister():
    unregister_class(StandoffPanel)

唯一的額外變化是 DemoRackPanel的類(lèi)定義,它與 bpy.types.Panel一起被StandoffPanel繼承。因?yàn)檫@不是DemoRack插件中的唯一Panel,它們都將位于 View 3D 側(cè)抽屜中的單個(gè)選項(xiàng)卡下,消除 3 行重復(fù)是一件簡(jiǎn)單的事情。layout.prop 的模式和相關(guān)函數(shù)中是將 Data 對(duì)象作為第一個(gè)參數(shù),并將該對(duì)象內(nèi)屬性的字符串標(biāo)識(shí)符作為第二個(gè)參數(shù)。

剩下要做的就是從DemoRack/src/目錄編譯DemoRack.zip文件,然后像其他任何文件一樣在編輯 > 首選項(xiàng) > 附加組件中安裝該本地文件。

原文鏈接:Build a Blender Add-on Ready to Scale

以上就是python可擴(kuò)展的Blender 3D插件開(kāi)發(fā)匯總的詳細(xì)內(nèi)容,更多關(guān)于python Blender 3D插件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python 實(shí)現(xiàn)仿微信聊天時(shí)間格式化顯示的代碼

    python 實(shí)現(xiàn)仿微信聊天時(shí)間格式化顯示的代碼

    這篇文章主要介紹了python 實(shí)現(xiàn)仿微信聊天時(shí)間格式化顯示,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-04-04
  • numpy中np.dstack()、np.hstack()、np.vstack()用法

    numpy中np.dstack()、np.hstack()、np.vstack()用法

    numpy里dstack, hstack, vstack, 都有拼接的作用,本文詳細(xì)的介紹了np.dstack()、np.hstack()、np.vstack()用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 一文帶你了解CNN(卷積神經(jīng)網(wǎng)絡(luò))

    一文帶你了解CNN(卷積神經(jīng)網(wǎng)絡(luò))

    CNN是神經(jīng)網(wǎng)絡(luò)中的一種,它的權(quán)值共享網(wǎng)絡(luò)結(jié)構(gòu)使之更類(lèi)似于生物神經(jīng)網(wǎng)絡(luò),降低了網(wǎng)絡(luò)模型的復(fù)雜度,減少了權(quán)值的數(shù)量。本文主要講解了CNN(卷積神經(jīng)網(wǎng)絡(luò))的基礎(chǔ)內(nèi)容,想了解更多的小伙伴可以看一看這篇文章
    2021-09-09
  • Python識(shí)別二維碼的兩種方法詳解

    Python識(shí)別二維碼的兩種方法詳解

    在學(xué)習(xí)Python處理二維碼的過(guò)程中,我們看到的大多是“用python生成酷炫二維碼”、“用Python制作動(dòng)圖二維碼”之類(lèi)的文章。而關(guān)于使用Python批量識(shí)別二維碼的教程,并不多見(jiàn)。本文就為大家總結(jié)了Python識(shí)別二維碼的兩種方法,感興趣的可以學(xué)習(xí)一下
    2022-06-06
  • Python中一行和多行import模塊問(wèn)題

    Python中一行和多行import模塊問(wèn)題

    我們通過(guò)本篇文章給大家分析了為什么Python不建議使用一行import所有模塊的原因,有興趣的朋友學(xué)習(xí)下。
    2018-04-04
  • Python?print函數(shù):如何將對(duì)象打印輸出

    Python?print函數(shù):如何將對(duì)象打印輸出

    這篇文章主要介紹了Python?print函數(shù):如何將對(duì)象打印輸出,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Python實(shí)現(xiàn)電視里的5毛特效實(shí)例代碼詳解

    Python實(shí)現(xiàn)電視里的5毛特效實(shí)例代碼詳解

    這篇文章主要介紹了Python實(shí)現(xiàn)了電視里的5毛特效,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • pyecharts繪制中國(guó)2020肺炎疫情地圖的實(shí)例代碼

    pyecharts繪制中國(guó)2020肺炎疫情地圖的實(shí)例代碼

    在本篇文章里小編給大家整理的是關(guān)于pyecharts繪制中國(guó)2020肺炎疫情地圖的實(shí)例代碼內(nèi)容,有興趣的朋友們可以測(cè)試下。
    2020-02-02
  • Python實(shí)戰(zhàn)之大魚(yú)吃小魚(yú)游戲的實(shí)現(xiàn)

    Python實(shí)戰(zhàn)之大魚(yú)吃小魚(yú)游戲的實(shí)現(xiàn)

    這篇文章主要介紹了如何利用Python制作一個(gè)經(jīng)典游戲之大魚(yú)吃小魚(yú),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下
    2022-04-04
  • 基于python讀取圖像的幾種方式匯總

    基于python讀取圖像的幾種方式匯總

    Python進(jìn)行圖片處理,第一步就是讀取圖片,下面這篇文章主要給大家介紹了關(guān)于基于python讀取圖像的幾種方式的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論