3d 如何展平选定的点

3d 如何展平选定的点,3d,maya,3d,Maya,我需要在局部法线轴上展平一组点。我假设,如果法线是正确的,那么无论他们是否从对象的任何一侧选择点,该轴都将始终相同 为了直观地展示我正在努力实现的目标,我想将此转变为: 以编程方式将其转换为: 如果我将缩放工具设置为“法线平均值”,并手动缩放它们,我可以将点展平到一个平面,但我需要计算或通过代码执行此操作 我看过这个命令,它有一个名为localScaleZ的标志,甚至在它的描述中写了“扁平化”,但我运气不好。有什么建议吗?最简单的方法就是使用与手动操作相同的操作。在mel中执行此操作的代码如

我需要在局部法线轴上展平一组点。我假设,如果法线是正确的,那么无论他们是否从对象的任何一侧选择点,该轴都将始终相同

为了直观地展示我正在努力实现的目标,我想将此转变为:

以编程方式将其转换为:

如果我将缩放工具设置为“法线平均值”,并手动缩放它们,我可以将点展平到一个平面,但我需要计算或通过代码执行此操作


我看过这个命令,它有一个名为localScaleZ的标志,甚至在它的描述中写了“扁平化”,但我运气不好。有什么建议吗?

最简单的方法就是使用与手动操作相同的操作。在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]))

最简单的方法是使用与手动操作相同的操作。在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]))

我从未使用过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_point

我从未使用过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_point


我对maya不太了解,也不知道它提供了什么样的数据,但给定某些数据,这可以作为几何问题来解决。你能说明一下你知道如何获取这些信息吗?例如,你有所有的点坐标吗?你有这些点形成的所有平面的列表吗(即,每组4个点的列表),等等…?有什么特别的原因必须用多边形移动面来完成吗?@entropy,我有选择的每个点的vactor坐标,法线方向,面法线,信息堆,我只是不知道如何处理它@Shannon Hochkins你能单独移动点吗?此外,将所有点移动到由所有选定点的四个角定义的平面上是否可行?是的,可行,是的,我可以通过一个循环单独移动它们。我不太了解maya,也不知道maya提供了什么样的数据,但给定某些数据,这可以作为几何问题解决。你能说明一下你知道如何获取这些信息吗?例如,你有所有的点坐标吗?你有这些点形成的所有平面的列表吗(即,每组4个点的列表),等等…?有什么特别的原因必须用多边形移动面来完成吗?@entropy,我有选择的每个点的vactor坐标,法线方向,面法线,信息堆,我只是不知道如何处理它@Shannon Hochkins你能单独移动点吗?另外,将所有点移动到由所有选定点的四个角定义的平面上是否可行?是的,可行,是的,我可以通过一个循环单独移动它们,因为scmh不再使用旋转和缩放。我无法运行@joojaa,我使用PolyMoveFact没有特殊原因,这只是我能找到的唯一相对的东西,当我在脚本编辑器中运行脚本时,它没有正确地计算“$p”,您是否设法让它工作?你选择了什么?别管@joojaa了,经过一段时间的努力,我还为你的帖子添加了一个Python版本,再次感谢!虽然我们在scale命令中都使用了“0,1,1”,但这并不总是正确的。不幸的是,有没有办法根据选择来计算这个值?是的,我现在可以看到我的错误了。我没有强调您需要选择缩放工具这一事实。我觉得这很明显,因为我正在做和你一样的事情。尽管有手册,但-mode的值确实上升到了9。方向可能没有更新,因为它使用工具操纵器,请尝试强制刷新。显然,你也可以手动进行法线计算。出于某种原因,scmh不再适用于旋转和缩放。我无法让它运行@joojaa,我使用PolyMoveFace没有什么特别的原因,这只是我在脚本编辑器中运行脚本时发现的唯一相对的东西,它没有正确地计算“$p”,你成功地使它工作了吗?你选择了什么?别管@joojaa了,经过一段时间的努力,我还为你的帖子添加了一个Python版本,再次感谢!虽然我们在scale命令中都使用了“0,1,1”,但这并不总是正确的。不幸的是,有没有办法根据选择来计算这个值?是的,我现在可以看到我的错误了。我没有强调您需要选择缩放工具这一事实。我觉得这很明显,因为我正在做和你一样的事情。尽管有手册,但-mode的值确实上升到了9。方向可能没有更新,因为它使用工具操纵器,请尝试强制刷新。很明显,你也可以手动计算法线。谢谢你发送这个!,你介意解释一下我需要定义哪些变量吗?他们会是什么样的人?示例:点,必须是选定点的数组?是的,点必须是点的数组。我假设每个点都有一个
normal
属性点本身和
normal
属性都有
x
y
z
属性。正如我所说,我从未使用过maya,所以我不知道actu是什么