3

私はPythonにかなり慣れていません(通常はc ++を使用しています)。レイ トレーシング アルゴリズムを使用して、Blender オブジェクトをバイナリ マスク ファイルに変換する Python スクリプトを作成しました。

私は巨大なメモリリークに終わっています。M = 512 (以下に示す) の場合、スクリプトを実行すると RAM の使用量が増加し、最終的に 5.7GB という途方もない量が使用されます。この RAM の使用量は、スクリプトが実行された後も、Blender を閉じるまで残ります。

コマンドが開いているファイルをRAMに保存するかどうかはわかりませんopen()が(おそらく保存していると思います)、これは結果のファイルサイズであるため、256MBのRAM使用量のみを説明し、RAM使用量の理由も説明しません残り後fo.close()

欠けている非常に単純なものがあると確信していますが、Pythonにあまり慣れていないため、それが何であるかを理解するのに苦労しています。pointInsideMesh()行を入れて、関数で使用されているすべての変数をクリアしようとしました

axis  = None
mat1  = None
mat   = None
orig  = None
count = None
location = None
normal   = None
index    = None
outside1 = None
outside2 = None

ステートメントの直前returnですが、これはメモリリークを塞いでいません。これが私のコードです:

import mathutils, numpy, bpy





def pointInsideMesh(point,ob):

    axes = [ mathutils.Vector((1,0,0)) ]
    outside1 = False
    for axis in axes:

        mat1 = mathutils.Matrix(ob.matrix_world)
        mat=mat1.invert()

        orig = mat1*point


        count = 0
        while True:
            location,normal,index = ob.ray_cast(orig,axis*10000.0)
            if index == -1: break
            count+= 1

            orig = location + axis*0.00001



        if (count%2 == 0):
            outside1 = True
            break




    axes = [ mathutils.Vector((0,1,0)) ]
    outside2 = False
    for axis in axes:

        mat1 = mathutils.Matrix(ob.matrix_world)
        mat=mat1.invert()

        orig = mat1*point


        count = 0
        while True:
            location,normal,index = ob.ray_cast(orig,axis*10000.0)
            if index == -1: break
            count+= 1

            orig = location + axis*0.00001



        if (count%2 == 0):
            outside2 = True
            break

    outside = outside1 or outside2
    return not outside




ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh( mathutils.Vector(((l+1)/M-0.5,(m+1)/M-0.5,(n+1)/M-0.5)), ob ):
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

どんな助けでも大歓迎です:)

アップデート:

import mathutils, numpy, bpy

def pointInsideMesh(point,ob):
    return False

ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh( mathutils.Vector(((l+1)/M-0.5,(m+1)/M-0.5,(n+1)/M-0.5)), ob ):
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

問題を再現しますが、

import mathutils, numpy, bpy

def pointInsideMesh():
    return False

ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh():
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

唯一の違いは、これら 2 つの最初の例では、テストされるポイント (およびオブジェクト) の位置が関数に渡されるのに対し、2 番目の例では引数が渡​​されないことです。C++ では、値渡しを行った場合でも、関数内で作成された引数のコピーは、関数の戻り時にメモリからクリアされます。しかし、Pythonでは引数の渡し方が異なります。これが問題の原因であるに違いありません。これがどのように機能するのかよくわかりません。

4

1 に答える 1

0

メモリ リークの原因となる唯一のものは、obオブジェクトです。

あなたはそのオブジェクトの時間に何かをします512^3ob.ray_castオブジェクトにデータを保存する場合ob、それが問題であることがわかります。交換してみる

ob.ray_cast(orig,axis*10000.0)

3 つの静的な値を使用して、メモリの問題が続くかどうかを確認します。Blender の C 側でメモリ リークが発生している可能性があります。

于 2013-07-11T04:35:40.077 に答える