閉じた領域で頂点の位置を順番にインデックス付けするにはどうすればよいですか?

Aug 20 2020

このビデオのように、効果を出すには頂点を順番に並べ替える必要があります。手で描く必要があることはわかっていますが、エッジを細分割すると、頂点インデックスが変わることがあります。

下の画像の頂点は正しいです。

たとえば、下の画像の頂点はランダムに並べ替えられています。それらを順番に並べ替えることができますか?

x軸またはz軸に沿って並べ替えようとしましたが、機能しませんでした。

ソリューションは複雑な形状でも機能するはずだと考えてください。

回答

11 batFINGER Aug 20 2020 at 15:08

頂点インデックスの並べ替え。

ここに答える https://blender.stackexchange.com/a/36619/15543 は、bmeshを使用して頂点インデックスを並べ替える方法を示しています。

ここに答える位置に基づいて頂点のリストを並べ替える方法は?注文のために端を歩く方法を示すために何らかの方法で行きます。

確実に、最初の頂点が(ループであるため)再遭遇するまで上記のようにエッジを歩き、これを注文に使用します。ここにあるものからスクリプトをつなぎ合わせるのはあなたに任せます

@Leanderの答えに示されているように

最短経路

bpy.ops.mesh.shortest_path_select()に相当するbmeshとは何ですか?のスクリプトを使用します。最初と最後のインデックス頂点間のリンクとしてエッジを選択し、一時的に削除し、2つの頂点のエッジから残りの最短パス(唯一のパス)を見つけることができます。エッジを元に戻します。

面巻き順序

上記のような閉ループの代わりに、競合はngonで埋めることができ、順序(巻き取り順序)としてngon面の頂点を使用して、頂点を再ソートし、作成されたngon面を削除します。

import bpy
import bmesh

ob = bpy.context.object
assert ob.type == "MESH"
me = ob.data

bm = bmesh.from_edit_mesh(me)

f = bmesh.ops.contextual_create(
        bm,
        geom=bm.verts[:] + bm.edges[:],
        )["faces"][0]

for i, v in enumerate(f.verts):
    v.index = i
bm.verts.sort()
bm.faces.remove(f)

bmesh.update_edit_mesh(me)

最初の頂点と時計回りまたはカウンターを選択します

ゼロ番目の頂点を選択し、反時計回り(上面図から)のインデックス作成を確実にするには

編集モードで実行し、インデックス0を設定する頂点を選択します。形状がXY平面にあると想定します。作成された面の法線が下を向いている場合、巻線が反転します。

ランダムな順序、頂点22が選択され、以下のスクリプトが実行されます

import bpy
import bmesh
from mathutils import Vector

ob = bpy.context.object
assert ob.type == "MESH"
me = ob.data

bm = bmesh.from_edit_mesh(me)
v0 = bm.select_history.active
f = bmesh.ops.contextual_create(
        bm,
        geom=bm.verts[:] + bm.edges[:],
        )["faces"][0]

fverts = f.verts[:]

if f.normal.dot((0, 0, 1)) < 0:
    fverts.reverse()

for i, v in enumerate(fverts):
    v.index = i
    if v is v0:
        iv0 = i

for v in fverts:
    v.index = (v.index - iv0) % len(fverts) 
    
bm.verts.sort()

bm.faces.remove(f)

bmesh.update_edit_mesh(me) 
6 Leander Aug 20 2020 at 14:33
  1. シェイプキーを追加します。
  2. そのシェイプキーで、最初と最後になる頂点をx軸上で互いに遠くに配置します。
  3. 他のすべて(頂点間)を選択します。
  4. W> [スムーズ頂点]を選択し、高い反復回数を設定します。頂点が滑らかになります。
  5. それらをx軸で並べ替えます。メッシュ>要素の並べ替え> X軸
  6. シェイプキーを削除します。

4 Leander Aug 20 2020 at 18:58

Pythonを使用すると、エッジを歩いて新しいインデックスを割り当てることができます。

import bpy
import bmesh

me = bpy.context.object.data
bm = bmesh.from_edit_mesh(me)

# index of the start vertex
initial = bm.verts[0]

vert = initial
prev = None
for i in range(len(bm.verts)):
    print(vert.index, i)
    vert.index = i
    next = None
    adjacent = []
    for v in [e.other_vert(vert) for e in vert.link_edges]:
        if (v != prev and v != initial):
            next = v
    if next == None: break
    prev, vert = vert, next

bm.verts.sort()

bmesh.update_edit_mesh(me)
2 RobinBetts Aug 21 2020 at 15:45

スクリプトなし:

  1. V 最初にしたい頂点でメッシュを分割します(まだ分割していない場合)。
  2. ヘッダー>オブジェクトメニュー>メッシュを曲線に変換
  3. 編集モード、メニューを右クリックし、必要に応じてスプラインの方向を切り替えます
  4. オブジェクトモード、右クリックメニュー、変換のメッシュバック。

メッシュのオブジェクトモードの右クリックメニューに[変換]が表示されない理由がわかりません。これはちょっと面倒です。

@Seyedによって提供される改良を除けば、スクリプトは次のようになります。

import bpy
bpy.ops.object.convert(target='CURVE', keep_original= False)
bpy.ops.object.convert(target='MESH', keep_original= False)