私は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では引数の渡し方が異なります。これが問題の原因であるに違いありません。これがどのように機能するのかよくわかりません。