可以使用简单的光线追踪技巧来测试您是在形状的内部还是外部。事实证明,2D,3D对象或什至更高尺寸的对象都具有整洁的属性。就是说,如果您朝任意方向发射任意射线,那么您将处于形状内部,并且仅当您达到形状边界和奇数次时。无需知道正常方向或其他任何信息。只知道您有几个路口。这很容易在2D中可视化,并且由于3D只是许多2D切片,同样适用于3D。
图1: 从任意方向的某个点发出光线,如果在内部,甚至在外部,则产生奇数次的命中,因此O 1在内部,而O
2在内部。作为一种特例,扫掠命中需要测试曲线,因为它们使2个命中在一个位置重合(O 3)。
图2: 网格化的曲面具有更好的边界条件,因为只有顶点命中会扫视,但是大多数跟踪引擎会忽略扫视命中,因为完全垂直的命中(O
4)会出现问题,因此在此测试中它们的行为正确。Maya跟踪器也不例外。
请注意,此方法不需要关闭曲面,但它只是有效地关闭了射线方向的缝隙,开放的曲面可能会报告怪异的结果,但它仍然有效。但是在某些情况下可以接受。
诚然,光线追踪是一项繁重的 *** 作,没有执行加速例程,但是一旦进行了加速,它就会变得非常快。Maya
API为此提供了一种方法。请注意,首先构建加速,然后每个后续调用都便宜得多。这是一个没有加速的快速编写的脚手架,有关如何加速的更多信息,请参阅
MFnMesh 文档。
import maya.cmds as cmdimport maya.OpenMaya as omdef test_if_inside_mesh(point=(0.0, 0.0, 0.0), dir=(0.0, 0.0, 1.0)): sel = om.MSelectionList() dag = om.MDagPath() #replace torus with arbitrary shape name sel.add("pTorusShape1") sel.getDagPath(0,dag) mesh = om.MFnMesh(dag) point = om.MFloatPoint(*point) dir = om.MFloatVector(*dir) farray = om.MFloatPointArray() mesh.allIntersections( point, dir, None, None, False, om.MSpace.kWorld, 10000, False, None, # replace none with a mesh look up accelerator if needed False, farray, None, None, None, None, None ) return farray.length()%2 == 1#testcmd.polyTorus()print test_if_inside_mesh()print test_if_inside_mesh((1,0,0))
在您的特定情况下,这可能是过大了。我假设您正在做某种拒绝采样。也可以用棱柱体构建主体,并使用重心状坐标随机化。这具有永不浪费结果的优点。但是跟踪代码通常更容易使用。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)