maya中的重叠顶点
Overlapping vertices in maya
我想找到距离小于 0.0003
和 return 的所有顶点作为列表。我使用以下算法,但对于大场景来说速度很慢。你有什么提高速度的秘诀吗?
listOfAllMesh = cmds.ls(geometry=True,type="mesh")
overlapping = []
for meshToCek in listOfAllMesh:
listOFVertex=[]
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
AllVertexes = cmds.ls(selection=True, flatten=True)
listOFVertex.append(AllVertexes[0])
Flag=False
for VertexToCek in AllVertexes[1:]:
c1=cmds.xform(VertexToCek, q=True, os=True, a=True, t=True)
for cek in listOFVertex:
c2=cmds.xform(cek, q=True, os=True, a=True, t=True)
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
if distance<0.0003:
overlapping.append(VertexToCek)
overlapping.append(cek)
Flag=True
if not Flag:
listOFVertex.append(VertexToCek)
Flag=False
return overlapping
@UnholySheep`s bb相交检查应该是第一步,但你的问题有两个主题:
- 首先是找到所有的顶点位置,快
python api in maya
- 第二个是比较N个点之间的距离,
numpy
真的很快
对于第二步,我建议编写您自己的可以调用 python 的 C 模块。创建一个沙盒 Maya 场景并通过不同的方法
测量时间
run_t = timeit.default_timer()
test_find_all_vertices_method_a()
print(timeit.default_timer() - run_t)
run_t = timeit.default_timer()
test_find_all_vertices_method_b()
print(timeit.default_timer() - run_t)
我希望我理解正确,您正在尝试针对自身测试对象的顶点!
我能想到的一些事情可能会减慢您的代码速度:
xform
可能是获取点位置的较慢方法。
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
这可能是另一个罪魁祸首。通常在计算距离时,平方根会减慢速度。绕过它的一种方法是改为计算平方距离,这样您就可以完全避免使用 math.sqrt
。
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
这可能不会减慢速度,但将顶点保存在内存中可能会更好。
我尝试使用最严格的 maya api 方法,性能似乎更好。也许有更好的优化方法,但我们在这里取得了一些进展!
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
def mfn_mesh_generator():
selection_list = OpenMaya.MSelectionList()
for mesh in cmds.ls(l=True, geometry=True,type="mesh"):
selection_list.add(mesh)
for i in range(selection_list.length()):
dag_path = OpenMaya.MDagPath()
selection_list.getDagPath(i, dag_path)
print dag_path.fullPathName()
mfn_mesh = OpenMaya.MFnMesh(dag_path)
yield mfn_mesh
def get_overlapping_vertices(mfn_mesh, threshold=0.0003):
points_list = OpenMaya.MPointArray()
mfn_mesh.getPoints(points_list, OpenMaya.MSpace.kWorld)
overlapping = []
for i in range(points_list.length()):
for j in range(points_list.length()):
if i == j:
continue
dist = points_list[i].distanceTo(points_list[j])
if dist < threshold:
if i not in overlapping:
overlapping.append(i)
if j not in overlapping:
overlapping.append(j)
return overlapping
for mfn_mesh in mfn_mesh_generator():
get_overlapping_vertices(mfn_mesh)
mfn_mesh_generator
是一个 python 生成器,您可以循环遍历场景中的所有 MFnMesh
对象。如果您想以另一种方式收集网格,请随意更改此设置(我这样做只是为了将事物分开并使其更通用)。幸运的是 api 的 MPoint
对象有一个方法 distanceTo
来计算另一个 MPoint
的距离!另外 MFnMesh
有一种方法可以用 getPoints
一举获得所有顶点。这比一个一个地优化它。
对于 5 个多边形球体的场景,大约需要 0.667850017548
秒。使用您的方法处理同一场景大约需要 12.1129710674
秒。相当不错的速度提升!
希望对您有所帮助并给您一些想法。
我想找到距离小于 0.0003
和 return 的所有顶点作为列表。我使用以下算法,但对于大场景来说速度很慢。你有什么提高速度的秘诀吗?
listOfAllMesh = cmds.ls(geometry=True,type="mesh")
overlapping = []
for meshToCek in listOfAllMesh:
listOFVertex=[]
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
AllVertexes = cmds.ls(selection=True, flatten=True)
listOFVertex.append(AllVertexes[0])
Flag=False
for VertexToCek in AllVertexes[1:]:
c1=cmds.xform(VertexToCek, q=True, os=True, a=True, t=True)
for cek in listOFVertex:
c2=cmds.xform(cek, q=True, os=True, a=True, t=True)
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
if distance<0.0003:
overlapping.append(VertexToCek)
overlapping.append(cek)
Flag=True
if not Flag:
listOFVertex.append(VertexToCek)
Flag=False
return overlapping
@UnholySheep`s bb相交检查应该是第一步,但你的问题有两个主题:
- 首先是找到所有的顶点位置,快 python api in maya
- 第二个是比较N个点之间的距离, numpy 真的很快
对于第二步,我建议编写您自己的可以调用 python 的 C 模块。创建一个沙盒 Maya 场景并通过不同的方法
测量时间run_t = timeit.default_timer()
test_find_all_vertices_method_a()
print(timeit.default_timer() - run_t)
run_t = timeit.default_timer()
test_find_all_vertices_method_b()
print(timeit.default_timer() - run_t)
我希望我理解正确,您正在尝试针对自身测试对象的顶点!
我能想到的一些事情可能会减慢您的代码速度:
xform
可能是获取点位置的较慢方法。
distance = math.sqrt(math.pow(c2[0] - c1[0], 2) + math.pow(c2[1] - c1[1], 2) + math.pow(c2[2] - c1[2], 2))
这可能是另一个罪魁祸首。通常在计算距离时,平方根会减慢速度。绕过它的一种方法是改为计算平方距离,这样您就可以完全避免使用 math.sqrt
。
cmds.select(meshToCek)
mel.eval("ConvertSelectionToVertices")
这可能不会减慢速度,但将顶点保存在内存中可能会更好。
我尝试使用最严格的 maya api 方法,性能似乎更好。也许有更好的优化方法,但我们在这里取得了一些进展!
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
def mfn_mesh_generator():
selection_list = OpenMaya.MSelectionList()
for mesh in cmds.ls(l=True, geometry=True,type="mesh"):
selection_list.add(mesh)
for i in range(selection_list.length()):
dag_path = OpenMaya.MDagPath()
selection_list.getDagPath(i, dag_path)
print dag_path.fullPathName()
mfn_mesh = OpenMaya.MFnMesh(dag_path)
yield mfn_mesh
def get_overlapping_vertices(mfn_mesh, threshold=0.0003):
points_list = OpenMaya.MPointArray()
mfn_mesh.getPoints(points_list, OpenMaya.MSpace.kWorld)
overlapping = []
for i in range(points_list.length()):
for j in range(points_list.length()):
if i == j:
continue
dist = points_list[i].distanceTo(points_list[j])
if dist < threshold:
if i not in overlapping:
overlapping.append(i)
if j not in overlapping:
overlapping.append(j)
return overlapping
for mfn_mesh in mfn_mesh_generator():
get_overlapping_vertices(mfn_mesh)
mfn_mesh_generator
是一个 python 生成器,您可以循环遍历场景中的所有 MFnMesh
对象。如果您想以另一种方式收集网格,请随意更改此设置(我这样做只是为了将事物分开并使其更通用)。幸运的是 api 的 MPoint
对象有一个方法 distanceTo
来计算另一个 MPoint
的距离!另外 MFnMesh
有一种方法可以用 getPoints
一举获得所有顶点。这比一个一个地优化它。
对于 5 个多边形球体的场景,大约需要 0.667850017548
秒。使用您的方法处理同一场景大约需要 12.1129710674
秒。相当不错的速度提升!
希望对您有所帮助并给您一些想法。