1

Blender ファイル内のすべてのオブジェクトを解析し、名前でフィルター処理してから、特定の基準を満たしていることを確認するためのカスタム エクスポート スクリプトを作成しています。

Blender 2.68a を使用しています。いくつかの基本的な 2D および 3D メッシュと、テスト基準に合格しないはずのいくつかを含むブレンダー ファイルを作成しました。Blender 内の内部 Python コンソールで作業しています。Blender の Python 環境はカスタマイズされているため、これが Blender の Python API を操作する唯一の方法です。

for ループと D.objects イテレータを使用してオブジェクトを反復処理し、正規表現を使用して名前の一致をチェックし、次を使用してオブジェクトからメッシュを取得する方法を並べ替えました。

mesh = obj.to_mesh(C.scene, True, 'RENDER') #where obj is an bpy.data.object[index] in the scene
mesh.update(True, True) 
mesh.polygons[index].<long list of possible functions>

ポリゴンの配列にアクセスして、ポリゴンを形成するエッジを持つ一連の頂点があるかどうか、およびそれらのキー値が何であるかを知ることができます。

私が整理できないのは、ポリゴンが面なのか単なるポリゴンなのかをPythonコンソールから判断する方法です。組み込み関数はありますか、またはこれをプログラムで判断するためにどのようなテストを実行できますか? たとえば、面を持たない 4 つのエッジを持つメッシュ 4 つの頂点を持つことができます。これをエクスポートしたくありませんが、同じ 4 つの頂点/エッジを編集して面を配置すると、望ましい輸出になる。

誰でも bpy.data.object データ構造を説明したり、「顔」が保存されている場所を説明したりできますか? それは npolys 自体のプロパティであるかのように見えますが、API では明らかにされていません。これを明確にするための支援をいただければ幸いです。乾杯。

4

1 に答える 1

2

それで、私はblender.orgフォーラムでこの質問をしました。これを乗り越えるための自分の努力に行き詰まるたびに、何日もかかりました。

回答の短いリストは次のとおりです。

1) すべてのポリゴンは面です。ポリゴンとして保存されていない場合、面ではありません。
2) オブジェクトで to_mesh() 関数を使用すると、関数のコピーが返されるため、コピーに対して行われた選択がコンテキストに反映されないため、使用していた方法論に欠陥がありました。ライブ オブジェクトにアクセスする唯一の方法は、次を使用することです。

bpy.data.objects[<index or object name>].data.vertices[<index>].co[<0,1,2> which correspond to x,y,z respectively]  
bpy.data.objects[<index or object name>].data.polygons[<index>].edge_keys  

最初のものは、オブジェクト内のすべての頂点の順序付けられたインデックス (タイプが 'MESH' であると仮定) とそれらの座標へのアクセスを提供します。
2 番目のものは、エッジを表す順序付きペアの 2 次元配列にアクセスできます。タプル内に含まれる数値は、最初のコマンドの頂点リストのインデックス値に対応するため、エッジが通過する座標を取得できます。新しい BMesh オブジェクトを作成し、関心のあるオブジェクトを BMesh にコピーすることもできます。これにより、ライブ オブジェクトではアクセスできない多くの機能が提供されます。回答 3 のコードは、この例を示しています。

3)メッシュ内の面のチェックに関する私の質問への回答については、以下を参照してください。

オブジェクトに面があり、すべてのエッジが面の一部であるかどうかを判断する 1 つの方法は、上記のスレッドで役立つユーザー CoDEmanX によって書かれた次のコード スニペットを使用することです。

import bpy, bmesh 

for ob in bpy.context.scene.objects: 
    if ob.type != 'MESH': 
        continue
    bm = bmesh.new() 
    bm.from_object(ob, bpy.context.scene) 

    if len(bm.faces) > 0 and 0 not in (len(e.link_faces) for e in bm.edges): 
        print(ob.name, "is valid") 
    else: 
        print(ob.name, "has errors") 

すべてのオブジェクトをループさせたくなかったので、これを少し変更しました。代わりに、渡されたオブジェクトが有効な場合は true を返し、そうでない場合は false を返す関数としてこれを取得しました。これにより、アドオンが正規表現に一致する名前を持つオブジェクトのみを検証しようとするように、呼び出しをシリアル化できます。

def validate(obj):
    import bpy, bmesh 

    if obj.type == 'MESH':                
        bm = bmesh.new() 
        bm.from_object(obj, bpy.context.scene) 

        if len(bm.faces) > 0 and 0 not in (len(e.link_faces) for e in bm.edges): 
            return True
    return False
于 2013-10-01T14:52:47.153 に答える