MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8でAuto Mirrorアドオンを使って軸中央に頂点の無いモデルを左右対称にする

本日は Blender2.8 のビルドインアドオンの調査枠です。
Blender2.8でAuto Mirrorアドオンを使って軸中央に頂点の無いモデルを左右対称にする手順を記事にします。

Auto Mirror アドオン

オブジェクトをミラーするための機能が実装されたアドオンです。
ミラー加工の自動化のほか、複数選択でのミラーやワールド軸でのミラー設定などが行えます。
bookyakuno.com

アドオンの有効化

Auto Mirror アドオンは Blender に含まれているため、アドオンを有効化するだけで利用可能です。
Blender を起動し、メニューから 編集 -> プリファレンス を開きます。
f:id:bluebirdofoz:20200630221055j:plain

Blenderプリファレンスダイアログが開くので[アドオン]タブを開きます。
[Auto Mirror]を検索します。
f:id:bluebirdofoz:20200630221114j:plain

一覧にアドオンが表示されるので、チェックを入れて有効化します。
これでアドオンのインストールは完了です。
f:id:bluebirdofoz:20200630221123j:plain

アドオンを有効化すると[3Dビュー]のサイドバーに[編集]->[Auto Mirror]パネルが追加されます。
f:id:bluebirdofoz:20200630221136j:plain

オブジェクトをミラーする

Auto Mirror アドオンを使ってオブジェクトをミラーしてみます。
以下のような軸中央に頂点の無いモデルを用意しました。
f:id:bluebirdofoz:20200630221145j:plain

ミラーするオブジェクトを選択し、サイドバーの[編集]->[Auto Mirror]を開きます。
XYZ の軸方向を指定して[AutoMirror]を実行します。
f:id:bluebirdofoz:20200630221155j:plain

これでオブジェクトがミラーされます。
f:id:bluebirdofoz:20200630221206j:plain

ワイヤーフレームで確認すると、中央部分に頂点が作成された上でミラーが設定されていることが分かります。
f:id:bluebirdofoz:20200630221217j:plain

最新バージョンの取得

ビルドインのアドオンはバージョン 2.5.2 のものになっています。
2020/06/30現在、最新バージョン 2.9.2 が公開されています。
Auto Mirror アドオンの最新バージョンは以下で購入できます。
gumroad.com

最新バージョンで追加されている機能については以下のページが参考になります。
bookyakuno.com

Blender2.8で利用可能なpythonスクリプトを作る その45(カーブオブジェクトの長さ)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

カーブオブジェクトの長さ

カーブオブジェクトの長さを計算します。
複製したカーブオブジェクトをメッシュオブジェクトに変換して計算を行います。
メッシュオブジェクトは自動で削除されます。
・get_length_curve.py

# bpyインポート
import bpy

# 指定カーブオブジェクトの長さを取得する
def get_length_curve(arg_objectname="Default") -> float:
    """カーブオブジェクトの長さを計算する

    Args:
        arg_objectname (str, optional): 指定オブジェクト名. Defaults to "Default".

    Returns:
        float: カーブオブジェクトの長さ
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
        
    # オブジェクトがカーブであるか確認する
    if selectob.type != 'CURVE':
        # 指定オブジェクトがカーブでない場合は処理しない
        return False
    
    # 全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)
    
    # 指定オブジェクトを選択状態に変更する
    selectob.select_set(True)

    # オブジェクトを複製する
    bpy.ops.object.duplicate_move()

    # 複製オブジェクトを取得する
    duplicatob = bpy.context.scene.objects[-1]
    
    # 指定オブジェクトを選択状態に変更する
    selectob.select_set(False)

    # 指定オブジェクトを選択状態に変更する
    duplicatob.select_set(True)

    # カーブオブジェクトをメッシュオブジェクトに変換する
    bpy.ops.object.convert(target='MESH')

    # メッシュ情報を再取得する
    mesh = duplicatob.data

    # 辺情報を取得する
    edges = mesh.edges.values()

    # 頂点情報を取得する
    vertices = mesh.vertices.values()

    # 辺の長さの変数を初期化する
    curve_lenght = 0.0

    for edge in edges:
        # 辺の開始と終端の頂点を取得する
        vert_start, vert_end = edge.vertices

        # 辺の長さを計算する
        edge_length = (vertices[vert_start].co - vertices[vert_end].co).length

        # カーブ全体の長さに辺の長さを加算する
        curve_lenght = curve_lenght + edge_length

    # 複製オブジェクトを削除する
    bpy.data.objects.remove(duplicatob)

    return curve_lenght

# 関数の実行例
length = get_length_curve(arg_objectname="BezierCurve")
print("Curve_Length : " + str(length))

f:id:bluebirdofoz:20200629185605j:plain

アドオンバージョン

上記スクリプトをアドオン化してみました。
追加されるパネルのオブジェクトリストからカーブオブジェクトを選択し、実行ボタンをクリックします。
すると、数値欄に対象カーブオブジェクトの長さが表示されます。
・Addon_get_length_curve.py

# bl_infoでプラグインに関する情報の定義を行う
bl_info = {
    "name": "HoloMon Curve Check Addon",             # プラグイン名
    "author": "HoloMon",                             # 制作者名
    "version": (1, 0),                               # バージョン
    "blender": (2, 80, 0),                           # 動作可能なBlenderバージョン
    "support": "TESTING",                            # サポートレベル
    "category": "3D View",                           # カテゴリ名
    "location": "View3D > Sidebar > HoloMon",        # ロケーション
    "description": "Addon Curve Check",              # 説明文
    "location": "",                                  # 機能の位置付け
    "warning": "",                                   # 注意点やバグ情報
    "doc_url": "",                                   # ドキュメントURL
}

# 利用するタイプやメソッドのインポート
import bpy
from bpy.types import Operator, Panel, PropertyGroup
from bpy.props import PointerProperty, FloatProperty

# 継承するクラスの命名規則は以下の通り
# [A-Z][A-Z0-9_]*_(継承クラスごとの識別子)_[A-Za-z0-9_]+
# クラスごとの識別子は以下の通り
#   bpy.types.Operator  OT
#   bpy.types.Panel     PT
#   bpy.types.Header    HT
#   bpy.types.MENU      MT
#   bpy.types.UIList    UL

# Panelクラスの作成
# 参考URL:https://docs.blender.org/api/current/bpy.types.Panel.html
class HOLOMON_PT_addon_curve_check(Panel):
    # パネルのラベル名を定義する
    # パネルを折りたたむパネルヘッダーに表示される
    bl_label = "Curve Check Addon Panel"
    # クラスのIDを定義する
    # 命名規則は CATEGORY_PT_name
    bl_idname = "HOLOMON_PT_addon_curve_check"
    # パネルを使用する領域を定義する
    # 利用可能な識別子は以下の通り
    #   EMPTY:無し
    #   VIEW_3D:3Dビューポート
    #   IMAGE_EDITOR:UV/画像エディター
    #   NODE_EDITOR:ノードエディター
    #   SEQUENCE_EDITOR:ビデオシーケンサー
    #   CLIP_EDITOR:ムービークリップエディター
    #   DOPESHEET_EDITOR:ドープシート
    #   GRAPH_EDITOR:グラフエディター
    #   NLA_EDITOR:非線形アニメーション
    #   TEXT_EDITOR:テキストエディター
    #   CONSOLE:Pythonコンソール
    #   INFO:情報、操作のログ、警告、エラーメッセージ
    #   TOPBAR:トップバー
    #   STATUSBAR:ステータスバー
    #   OUTLINER:アウトライナ
    #   PROPERTIES:プロパティ
    #   FILE_BROWSER:ファイルブラウザ
    #   PREFERENCES:設定
    bl_space_type = 'VIEW_3D'
    # パネルが使用される領域を定義する
    # 利用可能な識別子は以下の通り
    # ['WINDOW'、 'HEADER'、 'CHANNELS'、 'TEMPORARY'、 'UI'、
    #  'TOOLS'、 'TOOL_PROPS'、 'PREVIEW'、 'HUD'、 'NAVIGATION_BAR'、
    #  'EXECUTE'、 'FOOTER'の列挙型、 'TOOL_HEADER']
    bl_region_type = 'UI'
    # パネルタイプのオプションを定義する
    # DEFAULT_CLOSED:作成時にパネルを開くか折りたたむ必要があるかを定義する。
    # HIDE_HEADER:ヘッダーを非表示するかを定義する。Falseに設定するとパネルにはヘッダーが表示される。
    # デフォルトは {'DEFAULT_CLOSED'}
    bl_options = {'DEFAULT_CLOSED'}
    # パネルの表示順番を定義する
    # 小さい番号のパネルは、大きい番号のパネルの前にデフォルトで順序付けられる
    # デフォルトは 0
    bl_order = 0
    # パネルのカテゴリ名称を定義する
    # 3Dビューポートの場合、サイドバーの名称になる
    # デフォルトは名称無し
    bl_category = "HoloMon"
 
    # 描画の定義
    def draw(self, context):
        # Operatorをボタンとして配置する
        draw_layout = self.layout
        # 要素行を作成する
        select_row = draw_layout.row()
        # オブジェクト選択用のカスタムプロパティを配置する
        select_row.prop(context.scene.holomon_curvecheck, "prop_objectslect", text='')
        # 要素行を作成する
        length_row = draw_layout.row()
        # カーブオブジェクトの長さ表示用のカスタムプロパティを配置する
        length_row.prop(context.scene.holomon_curvecheck, "prop_curvelength")
        # 操作を無効化しておく
        length_row.enabled = False
        # 要素行を作成する
        button_row = draw_layout.row()
        # オブジェクト指定のサイズ縮小を実行するボタンを配置する
        button_row.operator("holomon.curvecheck")

# Operatorクラスの作成
# 参考URL:https://docs.blender.org/api/current/bpy.types.Operator.html
class HOLOMON_OT_addon_curve_check(Operator):
    # クラスのIDを定義する
    # (Blender内部で参照する際のIDに利用)
    bl_idname = "holomon.curvecheck"
    # クラスのラベルを定義する
    # (デフォルトのテキスト表示などに利用)
    bl_label = "CURVE CHECK"
    # クラスの説明文
    # (マウスオーバー時に表示)
    dl_description = "Curve Check Addon Description"
    # クラスの属性
    # 以下の属性を設定できる
    #   REGISTER      : Operatorを情報ウィンドウに表示し、やり直しツールバーパネルをサポートする
    #   UNDO          : 元に戻すイベントをプッシュする(Operatorのやり直しに必要)
    #   UNDO_GROUPED  : Operatorの繰り返しインスタンスに対して単一の取り消しイベントをプッシュする
    #   BLOCKING      : 他の操作がマウスポインタ―を使用できないようにブロックする
    #   MACRO         : Operatorがマクロであるかどうかを確認するために使用する
    #   GRAB_CURSOR   : 継続的な操作が有効な場合にオペレーターがマウスポインターの動きを参照して、操作を有効にする
    #   GRAB_CURSOR_X : マウスポインターのX軸の動きのみを参照する
    #   GRAB_CURSOR_Y : マウスポインターのY軸の動きのみを参照する
    #   PRESET        : Operator設定を含むプリセットボタンを表示する
    #   INTERNAL      : 検索結果からOperatorを削除する
    # 参考URL:https://docs.blender.org/api/current/bpy.types.Operator.html#bpy.types.Operator.bl_options
    bl_options = {'REGISTER', 'UNDO'}


    # Operator実行時の処理
    def execute(self, context):
        # カスタムプロパティから指定中のオブジェクトを取得する
        target_obj = context.scene.holomon_curvecheck.prop_objectslect

        # 指定中のオブジェクトを確認する
        if target_obj == None:
            # オブジェクトが指定されていない場合はエラーメッセージを表示する
            self.report({'ERROR'}, "No objects selected.")
            return {'CANCELLED'}

        # 指定のカーブオブジェクトの長さを取得する
        length = get_length_curve(arg_selectobj=target_obj)

        # カスタムプロパティにカーブの長さを設定する
        context.scene.holomon_curvecheck.prop_curvelength = length

        return {'FINISHED'}

# PropertyGroupクラスの作成
# 参考URL:https://docs.blender.org/api/current/bpy.types.PropertyGroup.html
class HOLOMON_addon_curve_check_properties(PropertyGroup):
    # オブジェクト選択時のチェック関数を定義する
    def prop_object_select_poll(self, context, ):
        # カーブオブジェクトのみ選択可能
        if(context and context.type in ('CURVE', )):
            return True
        return False

    # シーン上のパネルに表示するオブジェクト選択用のカスタムプロパティを定義する
    prop_objectslect: PointerProperty(
        name = "Select Object",         # プロパティ名
        type = bpy.types.Object,        # タイプ
        description = "",               # 説明文
        poll = prop_object_select_poll, # チェック関数
    )

    # シーン上のパネルに表示するオブジェクト選択用のカスタムプロパティを定義する
    prop_curvelength: FloatProperty(
        name = "Curve Length",         # プロパティ名
        description = "",               # 説明文
    )


# 登録に関する処理
# 登録対象のクラス名
regist_classes = (
    HOLOMON_PT_addon_curve_check,
    HOLOMON_OT_addon_curve_check,
    HOLOMON_addon_curve_check_properties,
)

# 作成クラスと定義の登録メソッド
def register():
    # カスタムクラスを登録する
    for regist_cls in regist_classes:
        bpy.utils.register_class(regist_cls)
    # シーン情報にカスタムプロパティを登録する
    bpy.types.Scene.holomon_curvecheck = PointerProperty(type=HOLOMON_addon_curve_check_properties)

# 作成クラスと定義の登録解除メソッド
def unregister():
    # シーン情報のカスタムプロパティを削除する
    del bpy.types.Scene.holomon_curvecheck
    # カスタムクラスを解除する
    for regist_cls in regist_classes:
        bpy.utils.unregister_class(regist_cls)


# 指定カーブオブジェクトの長さを取得する
def get_length_curve(arg_selectobj: bpy.types.Object) -> float:
    """カーブオブジェクトの長さを計算する

    Args:
        arg_selectobj (bpy.types.Object): 指定オブジェクト

    Returns:
        float: カーブオブジェクトの長さ
    """

    # 指定オブジェクトが存在するか確認する
    if arg_selectobj == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
        
    # オブジェクトがカーブであるか確認する
    if arg_selectobj.type != 'CURVE':
        # 指定オブジェクトがカーブでない場合は処理しない
        return False
    
    # 全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)
    
    # 指定オブジェクトを選択状態に変更する
    arg_selectobj.select_set(True)

    # オブジェクトを複製する
    bpy.ops.object.duplicate_move()

    # 複製オブジェクトを取得する
    duplicatob = bpy.context.scene.objects[-1]
    
    # 指定オブジェクトを選択状態に変更する
    arg_selectobj.select_set(False)

    # 指定オブジェクトを選択状態に変更する
    duplicatob.select_set(True)

    # カーブオブジェクトをメッシュオブジェクトに変換する
    bpy.ops.object.convert(target='MESH')

    # メッシュ情報を再取得する
    mesh = duplicatob.data

    # 辺情報を取得する
    edges = mesh.edges.values()

    # 頂点情報を取得する
    vertices = mesh.vertices.values()

    # 辺の長さの変数を初期化する
    curve_lenght = 0.0

    for edge in edges:
        # 辺の開始と終端の頂点を取得する
        vert_start, vert_end = edge.vertices

        # 辺の長さを計算する
        edge_length = (vertices[vert_start].co - vertices[vert_end].co).length

        # カーブ全体の長さに辺の長さを加算する
        curve_lenght = curve_lenght + edge_length

    # 複製オブジェクトを削除する
    bpy.data.objects.remove(duplicatob)

    return curve_lenght


# 実行時の処理
if __name__ == "__main__":
    # 作成クラスと定義を登録する
    register()

f:id:bluebirdofoz:20200629185550j:plain

Bevel Curve Toolsアドオンを使ってBlenderで髪の毛オブジェクトを作る その5(UVマップの調整)

本日は Blender の小ネタ枠です。
Bevel Curve Tools アドオンを使ってBlenderで髪の毛オブジェクトを作る手順を記事にします。

前回記事の続きです。
bluebirdofoz.hatenablog.com

UVマップの調整

毛並の方向を揃える

この状態で改めてUVマップを確認すると左右でUVマップの上下が反転していることが分かります。
毛並みの方向を揃えたいのでメッシュ上下の両端位置はUVマップ上の同じ位置に固定します。
f:id:bluebirdofoz:20200628190505j:plain

[編集モード]で上下両端のUVマップの頂点を選択します。
頂点を固定したい位置に移動させ、[UV]->[ピン止め]で位置を固定します。
f:id:bluebirdofoz:20200628190520j:plainf:id:bluebirdofoz:20200628190520j:plain

この状態で改めてUV展開を実行します。
すると同じ方向に毛並みが流れる形でUVマップを作成できました。
f:id:bluebirdofoz:20200628190534j:plain

メッシュサイズとの比率を合わせる

UVマップの方向を揃えることができましたが、自動で展開したため、マップのサイズが各オブジェクトで最大になっています。
このため、小さいオブジェクトではテクスチャの解像度が高く、大きいオブジェクトでは低くなってしまいます。
f:id:bluebirdofoz:20200628190550j:plain

[UVエディター]上で頂点を全選択して[拡大縮小]を実行し、サイズをオブジェクトとのサイズ比に合わせます。
f:id:bluebirdofoz:20200628190603j:plain

処理の自動化

上記の作業を全てのメッシュに実施します。
こちらの作業もスクリプト化しました。

毛並の方向を揃える処理

以下の記事の python スクリプトの関数を全てのオブジェクトに対して処理を行います。
bluebirdofoz.hatenablog.com

f:id:bluebirdofoz:20200628190700j:plain

毛並の方向を揃える処理

以下の記事の python スクリプトの関数を全てのオブジェクトに対して処理を行います。
bluebirdofoz.hatenablog.com

f:id:bluebirdofoz:20200628190636j:plain

これでBevel Curve Tools アドオンを使って作ったオブジェクトを元に、毛皮オブジェクトを作成することができました。
f:id:bluebirdofoz:20200628190830j:plain

Bevel Curve Toolsアドオンを使ってBlenderで髪の毛オブジェクトを作る その4(テクスチャの反映)

本日は Blender の小ネタ枠です。
Bevel Curve Tools アドオンを使ってBlenderで髪の毛オブジェクトを作る手順を記事にします。

前回記事の続きです。
bluebirdofoz.hatenablog.com

テクスチャの反映

今回は髪の毛オブジェクトにテクスチャを反映して、より髪の毛っぽい見た目にしていきます。
毛並の方向を揃えるため、個々のオブジェクト毎にテクスチャの反映を行っていきます。

UVマップを展開してマテリアルを設定する

既にメッシュを上下で分離しているのでそのままUV展開を行います。
[編集モード]に切り替えて、全ての面を選択した状態で[UV]->[展開]を実行し、UVマップを展開します。
f:id:bluebirdofoz:20200627223217j:plainf:id:bluebirdofoz:20200627223217j:plain

次にマテリアルを設定します。
[マテリアル]タブを開き、[新規]ボタンでマテリアルを作成します。
f:id:bluebirdofoz:20200627223233j:plain

マテリアルが生成されたらテクスチャを設定します。
[ベースカラー]のプルダウンを開き、[画像テクスチャ]を選択します。
f:id:bluebirdofoz:20200627223245j:plain

[開く]ボタンでファイル選択ダイアログを開き、反映するテクスチャを選択します。
f:id:bluebirdofoz:20200627223258j:plain

これでテクスチャが反映できました。
テクスチャを反映した状態の見た目は[3Dビューのシェーディング]を[マテリアルプレビュー]に変更することで確認できます。
f:id:bluebirdofoz:20200627223316j:plain

別オブジェクトのマテリアルを設定する

別オブジェクトもテクスチャを反映していきます。
2つ目以降のオブジェクトは先ほど作成したマテリアルを選択して反映します。
f:id:bluebirdofoz:20200627223332j:plain

処理の自動化

上記の作業を全てのメッシュに実施します。
こちらの作業もスクリプト化しました。
以下の記事の python スクリプトを元にマテリアルの作成と全オブジェクトへのマテリアル反映を行いました。
bluebirdofoz.hatenablog.com

f:id:bluebirdofoz:20200627223359j:plain

次はUVマップの調整を行います。
bluebirdofoz.hatenablog.com

Bevel Curve Toolsアドオンを使ってBlenderで髪の毛オブジェクトを作る その3(辺分離によるスムースシェードの修正)

本日は Blender の小ネタ枠です。
Bevel Curve Tools アドオンを使ってBlenderで髪の毛オブジェクトを作る手順を記事にします。

前回記事の続きです。
bluebirdofoz.hatenablog.com

陰影を修正する

スムーズシェードの影響を確認する

改めてオブジェクトを確認すると、淵の部分の陰影がおかしくなっている事に気付きます。
これは頂点数を削減したところにスムーズシェードを利用しているため、淵近くの法線が大きく歪んでいることが原因です。
f:id:bluebirdofoz:20200626125355j:plain

試しにスムーズシェードを無効化してみると、淵の部分のほとんどは本来、影が落ちないことが分かります。
シェードはオブジェクト毎に[オブジェクト]のプルダウンから[フラットシェード]または[スムースシェード]を選択できます。
f:id:bluebirdofoz:20200626125413j:plain

この縁の部分についてスムーズシェードを無効化します。
スムーズシェードは辺の分離を行うことにより、無効化できます。

シャープを設定する

スムーズシェードを無効化したい辺にシャープを設定していきます。
[編集モード]で辺を選択します。
f:id:bluebirdofoz:20200626125429j:plainf:id:bluebirdofoz:20200626125429j:plain

辺を選択した状態で [辺] -> [シャープをマーク] を設定します。
(画像差し込み_87)

これで縁の部分にシャープが設定されました。
f:id:bluebirdofoz:20200626125445j:plain

辺分離モディファイアを設定する

[オブジェクトモード]に戻ります。
アウトライナーウィンドウから対象のオブジェクトを選択して[モディファイア]タブを開きます。
f:id:bluebirdofoz:20200626125500j:plain

[モディファイアーを追加]プルダウンを開き、[辺分離]モディファイアを選択します。
f:id:bluebirdofoz:20200626125511j:plain

[辺分離]モディファイアが追加されたら、辺分離の対象で[シャープな辺]にチェックを入れます。
これで縁の部分にスムーズシェードがかからなくなり、綺麗な陰影になります。
f:id:bluebirdofoz:20200626125525j:plain

最後に[辺分離]モディファイアを[適用]します。
f:id:bluebirdofoz:20200626125539j:plain

処理の自動化

上記の作業を全てのメッシュに実施します。
こちらの作業もスクリプト化しました。
以下の記事の python スクリプトの関数を全てのオブジェクトに対して処理を行います。
bluebirdofoz.hatenablog.com

これで全てのメッシュオブジェクトの陰影を修正できました。
f:id:bluebirdofoz:20200626125610j:plain

次はテクスチャの反映です。
bluebirdofoz.hatenablog.com
bluebirdofoz.hatenablog.com

Bevel Curve Toolsアドオンを使ってBlenderで髪の毛オブジェクトを作る その2(メッシュへの変換とミラー)

本日は Blender の小ネタ枠です。
Bevel Curve Tools アドオンを使ってBlenderで髪の毛オブジェクトを作る手順を記事にします。

前回記事の続きです。
bluebirdofoz.hatenablog.com

曲線オブジェクトをメッシュに変更する

今回からは一旦 Bevel Curve Tools アドオンでの編集を確定して仕上げを行っていきます。
最初に、形状の編集を行えるようにするため、全ての曲線オブジェクトをメッシュに変更します。

アウトライナーウィンドウから全てのカーブオブジェクトを選択します。
[カーブ]タブから[To Mesh(es)]をクリックして、メッシュへの変換を行います。
f:id:bluebirdofoz:20200625222100j:plain

これで全てのオブジェクトがメッシュオブジェクトに変換されました。
f:id:bluebirdofoz:20200625222112j:plain

オブジェクトを左右対称にする

次に、各メッシュオブジェクトにミラーモディファイアを適用して左右対称にしていきます。
中央のメッシュオブジェクトを一例に手順を書き進めます。
f:id:bluebirdofoz:20200625222125j:plain

オブジェクトを半分にカットする

前回作成した曲線オブジェクトは断面を簡略化したため、下部の中央に頂点がありません。
このため、まずは中央の部分に頂点を作成する必要があります。
f:id:bluebirdofoz:20200625222144j:plain

今回は左右非対称な場合でも中央の部分に頂点を作成できるようブーリアンモディファイアを活用してみます。
最初にカット行う範囲を指定するためのキューブオブジェクトを作成します。
f:id:bluebirdofoz:20200625222156j:plain

以下のように左半分を覆う形で立方体オブジェクトを配置しました。
このとき、中央の点にピッタリ重なるように立方体を置くと、ブーリアンの演算がエラーを起こすので僅かにずらしています。
f:id:bluebirdofoz:20200625222209j:plain

再び、左右対称にしたいオブジェクトを選択して、[モディファイア]タブを開きます。
f:id:bluebirdofoz:20200625222225j:plain

[モディファイアーの追加]から[ブーリアン]モディファイアを選択します。
f:id:bluebirdofoz:20200625222237j:plain

[演算]に[差分]を選択し、[オブジェクト]に作成した[Cube]オブジェクトを指定します。
[重複のしきい値]は先ほどのずらしに合わせて調整します。
f:id:bluebirdofoz:20200625222248j:plain

これでオブジェクトが半分にカットされました。
最後に、ブーリアンモディファイアを適用します。
f:id:bluebirdofoz:20200625222302j:plain

立方体オブジェクトを非表示にすると、綺麗に分割されていることが分かります。
f:id:bluebirdofoz:20200625222316j:plain

ミラーを設定する

次にオブジェクトにミラーモディファイアを適用します。
今のままだと断面にメッシュが貼られているため、[編集モード]で面を選択して削除します。
f:id:bluebirdofoz:20200625222331j:plain

この状態でオブジェクトにミラーモディファイアを適用します。
f:id:bluebirdofoz:20200625222343j:plain

これでオブジェクトがミラーされ、左右対称なオブジェクトになりました。
[クリッピング]を有効にして、ブーリアンでのずらし分を[マージ]の結合距離に設定しておけば不要な頂点が削除されます。
f:id:bluebirdofoz:20200625222357j:plain

処理の自動化

上記の作業を全てのメッシュに実施します。
手作業で実施すると時間がかかる上、再加工が大変になってしまうのでスクリプト化しました。
以下の記事の python スクリプトの関数を全てのオブジェクトに対して処理を行います。
bluebirdofoz.hatenablog.com

これで左右対称なメッシュオブジェクトに加工することができました。
f:id:bluebirdofoz:20200625222423j:plain

次はシャープの設定と辺分離を使って陰影を修正します。
bluebirdofoz.hatenablog.com

Bevel Curve Toolsアドオンを使ってBlenderで髪の毛オブジェクトを作る その1

本日は Blender の小ネタ枠です。
前回紹介した Bevel Curve Tools アドオンを使ってBlenderで髪の毛オブジェクトを作る手順を記事にします。
bluebirdofoz.hatenablog.com

今回の作成物

ホロモンの首回りの毛皮のベースオブジェクトを Bevel Curve Tools アドオンを使って作り込みます。
以下のような完成図を目指します。
f:id:bluebirdofoz:20200624222254j:plain

基礎となる髪の毛オブジェクトの作成

Dual Tipオブジェクトの作成

髪の毛の束を幾つも重ね合わせるような形で作成していきます。
まずは基礎となるひとまとまりの髪の毛オブジェクトを作成します。

髪の毛オブジェクト作成用の Blender の新規オブジェクトを作成しました。
f:id:bluebirdofoz:20200624222408j:plain

[カーブ]タブ内の[New Beveled Curve]をクリックして曲線オブジェクトを生成します。
f:id:bluebirdofoz:20200624222424j:plain

最終的に左右対称なオブジェクトとしたいので、X軸に対して対称となるようオブジェクトを移動します。
カーブオブジェクトを選択し、[編集モード]に移行します。
f:id:bluebirdofoz:20200624222437j:plain

制御点を移動し、以下のように配置し直しました。
f:id:bluebirdofoz:20200624222450j:plain

[カーブ]タブの[Add/Override Bevel]をクリックして形状を再設定します。
ベースとなる曲線オブジェクトの[Radius Falloff]は[Dual Tip]に設定します。
今回はなるべくローポリゴンなオブジェクトとしたいので[タイプ]は[三角]としています。
f:id:bluebirdofoz:20200624222506j:plainf:id:bluebirdofoz:20200624222506j:plain

膨らみの部分形状は制御点を調整することで変更することができます。
f:id:bluebirdofoz:20200624222516j:plain

同じ作業を繰り返して曲線オブジェクトを追加していきます。
まずは凡その形が出来上がりました。
f:id:bluebirdofoz:20200624222528j:plain

One Tipオブジェクトの利用

次に厚みを付けていきます。
付け根の部分から重ねるように[Dual Tip]の曲線オブジェクトを追加していきます。
f:id:bluebirdofoz:20200624222546j:plain

ある程度、曲線オブジェクトを重ねたら、上端が隠れて見えない部分の曲線オブジェクトが出てきます。
こういったオブジェクトについては[Dual Tip]ではなく[One Tip]を利用すると、制御点が少ないため作業が短縮できます。
f:id:bluebirdofoz:20200624222605j:plain

今回は束の中央部分が膨らんだような形にしたかったので、最終的には全て[Doal Tip]を利用しました。
f:id:bluebirdofoz:20200624222626j:plain

オブジェクトのリダクション

このままだとポリゴン数が多いので、可能な限りリダクションしていきます。
まずは各曲線オブジェクトの解像度を調整して形が崩れない程度にポリゴン数を減らします。
f:id:bluebirdofoz:20200624222638j:plain

断面もポリゴン数を減らします。
曲線オブジェクトを一つ選択して[Edit Bevel]をクリックします。
f:id:bluebirdofoz:20200624222816j:plain

頂点を融解していき、なるべく断面が単純な形になるよう変更します。
f:id:bluebirdofoz:20200624222715j:plain

これで断面のポリゴン数が減りました。
f:id:bluebirdofoz:20200624222831j:plain

他の曲線オブジェクトも同様に断面を単純な形に変更します。
f:id:bluebirdofoz:20200624222845j:plain

これでポリゴン数を凡そ4分の1にすることができました。
スムースシェードの影響で影の付き方が変になってしまっていますが、これは後々修正を行います。
f:id:bluebirdofoz:20200624222857j:plain

次はこれらの曲線オブジェクトをメッシュオブジェクトに変換します。
bluebirdofoz.hatenablog.com