新四季網

blender入門及案例(Blender修改器開發入門)

2023-04-14 19:07:57 1

在Blender中,修改器(Modifier)是動態應用於網格的程序幾何效果,可實現靈活的非破壞性工作流程。這是為 Blender 2.80 添加新修改器的編程指南。

自定義修改器不能用 python 編寫,因此本指南將展示 Blender 的 C 代碼的哪些部分必須修改。

1、Blender源碼構建

由於我們要修改 Blender 的核心,首先需要從原始碼構建 Blender。這個過程在 Blender 的 Wiki: Building Blender中有詳細記錄。我將假設你遵循了有關目錄名稱的這些說明。

在實際開始修改代碼之前,建議創建一個分支以將我們的更改與上遊開發隔離。例如讓我們稱之為pizza-modifier:

/../blender-git/blender $ git checkout -b pizza-modifier

在這篇文章中,我們將添加一個「Pizza」修改器。我不知道它可以做什麼,但至少我們肯定不會被源庫中其他出現的「pizza」這個詞弄糊塗。

2、Pizza修改器概述

那麼,我們需要改變什麼?為什麼我們需要更改這麼多文件?顯然,我們至少必須對修改器本身的行為進行編碼。但我們還必須確保它在 UI 中列出,可以通過 Python API 訪問,並且它的參數保存在Blender文件中。最後一點是使用 Blender 架構核心的 DNA/RNA 機制實現的。

我們的大部分更改位於/../blender-git/blender/source/blender/modifiers/目錄。

3、Blender核心修改器

為Blender創建修改器意味著定義一個ModifierTypeInfo類型的全局變量。然後我們將它註冊到全局修改器列表中。為了匹配編碼風格並與現有宏很好地配合,此變量必須被命名為modifierType_Pizza,其中「Pizza」是你的實際修改器名稱的首字母大寫形式。

3.1 修改器類型信息

修改器類型信息變量通常在/../blender-git/blender/source/blender/modifiers/intern 文件夾中MOD_pizza.c文件中定義, 因此,創建此文件並將其添加到要在父目錄CMakeLists.txt 中的構建列表中,連同以 intern/MOD_開頭的所有其他行。

至少,你的MOD_pizza.c文件應當包含:

#include "BKE_modifier.h"ModifierTypeInfo modifierType_Pizza = { /* name */ "Pizza", /* StructName */ "PizzaModifierData", /* structSize */ sizeof(PizzaModifierData), /* type */ eModifierTypeType_None, /* flags */ 0, /* copyData */ NULL, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* applyModifier */ NULL, /* initData */ NULL, /* requiredDataMask */ NULL, /* freeData */ NULL, /* isDisabled */ NULL, /* updateDepsgraph */ NULL, /* dependsOnTime */ NULL, /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, /* foreachTexLink */ NULL, /* freeRuntimeData */ NULL,};

結構ModifierTypeInfo定義在source/blender/blenkernel/BKE_modifier.h 文件中,在我寫這篇文章時的第 139 行,即使用 Blender 2.80 RC時。不同欄位的含義在這個頭文件中有很好的解釋,所以你一定要看看。

我將專注於一些基本欄位,而將其他領域留給你探索,因為根據你的修改器要實現的任務,並不一定需要所有這些欄位。

3.2 類型和標誌

要設置的第一個欄位(在名稱之後)是修改器的類型,type 欄位。 這是在BKE_modifier.h的開頭定義的枚舉類型,因此再次查看選項以找到最適合你的修改器的匹配項。如果不確定,可以嘗試查看MOD_something.c 文件中具有類似行為的現有修改器。

另一個重要欄位是flags 。 同樣是一個在BKE_modifier.h中定義的枚舉。很可能你會用eModifierTypeFlag_AcceptsMesh來告訴 Blender 你的修改器可以處理網格數據。可以使用邏輯或運算符( |) 設置多個標誌。

3.3 應用修改器

修改器的核心是applyModifier 函數中實現的功能。在定義修改器類型信息變量之前,定義一個函數,如:

#include "DNA_mesh_types.h"static Mesh *pizza_applyModifier(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh){ return mesh;}

並將applyModifier欄位設置為pizza_applyModifier ,或者你為上述函數提供的任何名稱。此功能將是修改器進行所有處理的地方。這完全取決於你自己,返回的網格可以是使用source/blender/blenkernel/BKE_mesh.h中的函數創建的新網格,請參見附錄中的示例。

3.4 其他欄位

對於某些欄位,可以使用定義在BKE_modifier.h 中的工具方法。例如,可以設置copyData為modifier_copyData_generic 。

4、DNA和RNA

ModifierTypeInfo 中有兩個非常重要的欄位我還沒有提到:structName和structSize。它們指向的PizzaModifierData結構將成為我們修改器的DNA。

DNA 是.blend文件保存在磁碟上的內容。它必須包含所有保存的參數。按照生物學的比喻,每個 DNA 都與一個 RNA 結構相關聯。這個僅在運行時使用,用於編輯、傳輸、撤消、重做等與修改器相關的數據。

4.1 DNA

Blender 中使用的所有 DNA 結構都在source/blender/makesdna/目錄中定義。修改器定義在DNA_modifier_types.h 文件中。

首先要修改的是:添加eModifierType_Pizza到ModifierType文件開頭的枚舉中,就放在NUM_MODIFIER_TYPES 前面。 這個枚舉不能重新排序,因為枚舉值是保存在混合文件中的,所以它會破壞向後兼容性。這也是明確說明枚舉值的原因。

在文件末尾,我們為修改器添加 DNA 結構。它的第一個欄位必須是 type ModifierData。它是一種繼承機制,可以將指向結構的指針用作更通用的ModifierData*。

typedef struct PizzaModifierData { ModifierData modifier; int num_olives; int _pad0;} PizzaModifierData;

在這個例子中,我們的修改器有一個整型參數num_olives。

另一個要求是填充結構以使其整體大小為 8 字節的倍數。如果不是自然情況,請添加額外的_pad 前綴的欄位以達到 8 的倍數。

請注意,整個文件是在構建 Blender 之前通過執行特殊程序makesdna處理的,因此這裡不能使用花哨的東西或預處理器宏。

注意:由於我們在修改器類型信息中指向的是 DNA 結構,因此必須將DNA_modifier_types.h 其包含在MOD_pizza.c文件中。

4.2 RNA

RNA 機制位於source/blender/makesrna/ 目錄中。與 DNA 類似,intern中的文件在Blender構建之前由一個名為makesrna 的定製程序處理, 這使我們免於執行一些關於 DNA/RNA 轉換的非常重複的任務。

修改器的 RNA 定義在 makesrna/intern/rna_modifier.c 文件中。除非你用 DNA 製作高級的東西,否則你將主要需要編寫一個類似於所有其他已經存在的簡單函數 rna_def_modifier_pizza ,把這個函數添到 void RNA_def_modifier(BlenderRNA *brna) 之前:

static void rna_def_modifier_pizza(BlenderRNA *brna){ StructRNA *srna; PropertyRNA *prop; // Define the RNA and bind it to the PizzaModifierData DNA struct srna = RNA_def_struct(brna, "PizzaModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Pizza Modifier", ""); RNA_def_struct_sdna(srna, "PizzaModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_ARRAY); // There will be such a block for each data field of PizzaModifierData prop = RNA_def_property(srna, "num_olives", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_range(prop, 0, 100, 1, -1); RNA_def_property_ui_text(prop, "Olives", "The number of olives on the pizza"); RNA_def_property_update(prop, 0, "rna_Modifier_update");}

注意:您可以為您的 RNA 選擇自定義圖標,而不是ICON_MOD_ARRAY我在此處選擇的圖標。

在 RNA_def_modifier的最後,添加對我們剛剛定義的rna_def_modifier_pizza(brna)函數的調用。

4.3 修改器類型枚舉

由於修改了ModifierType枚舉的 DNA,我們還需要編輯它的 RNA。為此,請在相應rna_modifier.c部分的開頭為rna_enum_object_modifier_type_items添加一個條目。節標題是{0, "", 0, N_("Modify"), ""}類型的行。它們與添加新修改器時顯示在 UI 中的下拉菜單直接相關。第二個參數是用於繪製 UI 的 Python 函數的名稱,見下文。

我們還必須編輯要在/* Default */之前添加的rna_Modifier_refine 函數:

case eModifierType_Pizza: return &RNA_PizzaModifier;

注意:變量RNA_PizzaModifier不需要我們自己定義,它會由makesrna生成。

因此,我們完成了與 DNA/RNA 相關的更改。你可能對修改器參數有一些更高級的需求。如果是這樣,請隨意查看其他修改器如何處理特殊情況,它們都定義在同一個文件中。

注意:有關 RNA 的更多詳細信息,可以查看此存檔。

5、用戶界面

修改器的用戶界面在 Python 腳本中定義:release/scripts/startup/bl_ui/properties_data_modifier.py.

向DATA_PT_modifiers類添加繪圖方法def PIZZA(self, layout, ob, md):,類似於其他修改器已經存在的功能。函數的名稱必須與上面rna_enum_object_modifier_type_items( rna_modifier.c)中定義的條目匹配。例如:

# in class DATA_PT_modifiersdef PIZZA(self, layout, ob, md): layout.prop(md, "num_olives")

注意:構建時,請確保將此 python 文件複製到2.80/scripts/startup/bl_ui目錄中。可能需要手動複製它。

6、最後的步驟

我們的修改器有一個核心,通過 DNA 存儲在Blender文件中並通過 RNA 傳輸,但我們仍然需要在其他地方註冊它。

6.1 修改器表

修改器的類型信息需要在全局修改器表中註冊。這是通過在modifier_type_init原型之前的source/blender/modifiers/MOD_modifiertypes.h末尾添加以下行來完成的:

extern ModifierTypeInfo modifierType_Pizza;

在source/blender/modifiers/intern/MOD_util.c 中,#undef INIT_TYPE 之前:

INIT_TYPE(Pizza);

6.2 大綱

大綱是 UI 空間,可以列出有關當前打開的Blender文件的所有技術細節。因此它必須知道所有的修改器,包括我們新的 Pizza 修飾符。在 source/blender/editors/space_outliner/outliner_draw.c 中編輯tree_element_get_icon函數以添加適當的case eModifierType_Pizza 。 不過,我不知道為什麼它不能從 RNA 中獲取這條信息。

7、結論

現在,你的修改器有了第一個骨架。從現在開始,你將能夠通過閱讀BKE_modifier.h 的注釋或其他修飾符的實現來學到很多東西。

原文連結:http://www.bimant.com/blog/custom-blender-modifier/

,
同类文章
葬禮的夢想

葬禮的夢想

夢見葬禮,我得到了這個夢想,五個要素的五個要素,水火只好,主要名字在外面,職業生涯良好,一切都應該對待他人治療誠意,由於小,吉利的冬天夢想,秋天的夢是不吉利的
找到手機是什麼意思?

找到手機是什麼意思?

找到手機是什麼意思?五次選舉的五個要素是兩名士兵的跡象。與他溝通很好。這是非常財富,它擅長運作,職業是仙人的標誌。單身男人有這個夢想,主要生活可以有人幫忙
我不怎麼想?

我不怎麼想?

我做了什麼意味著看到米飯烹飪?我得到了這個夢想,五線的主要土壤,但是Tu Ke水是錢的跡象,職業生涯更加真誠。他真誠地誠實。這是豐富的,這是夏瑞的巨星
夢想你的意思是什麼?

夢想你的意思是什麼?

你是什​​麼意思夢想的夢想?夢想,主要木材的五個要素,水的跡象,主營業務,主營業務,案子應該抓住魅力,不能疏忽,春天夢想的吉利夢想夏天的夢想不幸。詢問學者夢想
拯救夢想

拯救夢想

拯救夢想什麼意思?你夢想著拯救人嗎?拯救人們的夢想有一個現實,也有夢想的主觀想像力,請參閱週宮官方網站拯救人民夢想的詳細解釋。夢想著敵人被拯救出來
2022愛方向和生日是在[質量個性]中

2022愛方向和生日是在[質量個性]中

[救生員]有人說,在出生88天之前,胎兒已經知道哪天的出生,如何有優質的個性,將走在什麼樣的愛情之旅,將與生活生活有什么生活。今天
夢想切割剪裁

夢想切割剪裁

夢想切割剪裁什麼意思?你夢想切你的手是好的嗎?夢想切割手工切割手有一個真正的影響和反應,也有夢想的主觀想像力。請參閱官方網站夢想的細節,以削減手
夢想著親人死了

夢想著親人死了

夢想著親人死了什麼意思?你夢想夢想你的親人死嗎?夢想有一個現實的影響和反應,還有夢想的主觀想像力,請參閱夢想世界夢想死亡的親屬的詳細解釋
夢想搶劫

夢想搶劫

夢想搶劫什麼意思?你夢想搶劫嗎?夢想著搶劫有一個現實的影響和反應,也有夢想的主觀想像力,請參閱週恭吉夢官方網站的詳細解釋。夢想搶劫
夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂什麼意思?你夢想缺乏異常藥物嗎?夢想缺乏現實世界的影響和現實,還有夢想的主觀想像,請看官方網站的夢想組織缺乏異常藥物。我覺得有些東西缺失了