我需要在点的局部法线轴上展平所选的点。我假设如果法线是正确的,那么无论他们从对象的任何一侧选择点,这个轴都是相同的?
为了直观地表示我正在尝试实现的目标,我想将其转换为:

以编程的方式添加到其中:

如果我将我的缩放工具设置为'Normals Average',并手动缩放它们,我可以将这些点展平到一个平面上,但是我需要通过代码来计算或执行此操作。
我看过polyMoveFacet命令,它有一个名为localScaleZ的标志,它的描述中甚至写着“展平”,但我一直没有运气。有什么建议吗?
发布于 2013-03-07 02:24:41
最简单的方法就是使用您手动执行的相同操作。在mel中执行此操作的代码将如下所示:
{ // protect global namespace
setToolTo Scale;
manipScaleContext -e -mode 9 Scale;
$oa = `manipScaleContext -q -orientAxes Scale`;
$p = `manipScaleContext -q -position Scale`;
scale -ws -r
-p ($p[0]) ($p[1]) ($p[2])
-oa ($oa[0]+"rad") ($oa[1]+"rad") ($oa[2]+"rad")
0 1 1;
}和Python:
cmds.setToolTo('Scale')
cmds.manipScaleContext("Scale", e=1, mode=9)
p = cmds.manipScaleContext("Scale", q=1, p=1)
oa = cmds.manipScaleContext("Scale", q=1, oa=1)
cmds.scale(0,1,1,
p=(p[0],p[1],p[2]),
oa=("%srad"%oa[0],"%srad"%oa[1],"%srad"%oa[2]))发布于 2013-03-07 06:57:55
我从未使用过maya,也不知道它使用的是什么脚本语言。因此,这个答案只涉及到问题的数学/几何方法。代码是用python编写的,用来演示这个概念,但你应该能够翻译。
请注意,我没有测试代码,但希望它至少能为您提供解决问题的工具。
from math import sqrt
def point_average(points):
l = len(points)
return [(p.x/l,p.y/l,p.z/l) for p in points]
def find_normal(points):
normal = point_average([p.normal for p in points])
normal_length = sqrt(sum(c**2 for c in normal))
normal = [c/normal_length for c in normal]
return normal
def find_plane(points):
normal = find_average_normal(points)
center = point_average(points)
# a point and a normal are enough to uniquely identify a plane
# we anchor the plane to the farthest point from the center
# that should be one of the corners
dcenter = lambda p:sqrt((p.x-center.x)**2+(p.y-center.y)**2+(p.z-center.z)**2)
points = [(dcenter(p),p) for p in points]
points.sort()
anchor = points[-1][1]
return (anchor,normal)
def project_point_onto_plane(point, plane):
anchor,normal = plane
# kudos to http://stackoverflow.com/questions/9605556/how-to-project-a-3d-point-to-a-3d-plane
# for the math behind this
v = (point.x-anchor[0], point.y-anchor[1], point.z-anchor[2])
dist = v[0]*normal[0] + v[1]*normal[1] + v[2]*normal[2]
projected_point = (point.x-dist*normal[0],
point.y-dist*normal[1],
point.z-dist*normal[1])
return projected_pointhttps://stackoverflow.com/questions/15248286
复制相似问题