【问题标题】:How to fix 'TypeError: in method 'MFnMesh_anyIntersection', argument 4 of type 'MIntArray const *' error in Python in Maya如何修复'TypeError:在方法'MFnMesh_anyIntersection'中,Maya中Python中'MINtArray const *'类型的参数4错误
【发布时间】:2023-03-09 00:25:01
【问题描述】:

我想用 Python 在 Maya 中使用 OpenMaya.MFnMesh.anyIntersection() 尝试一些光线投射。

我只想从物体上向下投射光线并击中飞机,而不是进一步,所以我只得到一个 raycasthit 并从 raycasthit 中获取平移值。

我从视频中得到了代码,并使其更清晰易懂。

为了使代码在 Maya 中正常运行,您需要一个在 Y 轴上高于其他对象的对象,最好是 polyPlane(例如:在位置 [0, 3, 0] 有一个 polySphere 和一个 polyPlane在 [0, 0, 0] 位置,选择 polySphere 并运行代码)

import maya.OpenMaya as OpenMaya
import maya.cmds as cmds

def RayReposition(*args):
    direction = (0.0, -1, 0)
    sel = cmds.ls(sl = True)

    fromPositionRay = cmds.xform(sel[0], query = True, translation = True)
    selShape = cmds.listRelatives(shapes = True)
    meshes = cmds.ls(geometry = True)

    cmds.select(clear = True)

    for x in meshes:
        if x == selShape[0]:
            continue
        else:
            OpenMaya.MGlobal.selectByName(x)
            sList = OpenMaya.MSelectionList()

            OpenMaya.MGlobal.getActiveSelectionList(sList)
            item = OpenMaya.MDagPath()
            sList.getDagPath(0, item)
            item.extendToShape()

            fnMesh = OpenMaya.MFnMesh(item)

            raySource = OpenMaya.MFloatPoint(fromPositionRay[0], fromPositionRay[1], fromPositionRay[2], 1.0)
            rayDir = OpenMaya.MFloatVector(direction[0], direction[1], direction[2])
            faceIds = None
            triIds = None
            idsSorted = False
            testBothDirections = False
            worldSpace = OpenMaya.MSpace.kWorld
            maxParam = 999999
            accelParams = None
            sortHits = True
            hitPoints = OpenMaya.MFloatPointArray()

            hitRayParams = OpenMaya.MFloatArray()
            hitFaces = OpenMaya.MIntArray()
            hitTris = None
            hitBarys1 = None
            hitBarys2 = None
            tolerance = 0.0001

            hit = fnMesh.anyIntersection(raySource, rayDir, worldSpace, maxParam, testBothDirections, faceIds, triIds, idsSorted, accelParams, tolerance, hitPoints, hitRayParams, hitFaces, hitTris, hitBarys1, hitBarys2)

            OpenMaya.MGlobal.clearSelectionList()
            firstHit = (hitPoints[0].x, hitPoints[0].y, hitPoints[0].z)
            print firstHit

RayReposition()

我希望从 raycasthit 中获取翻译值,但我收到以下错误:

TypeError: in method 'MFnMesh_anyIntersection', argument 4 of type 'MIntArray const *'

使用 OpenMaya.MFnMesh.allIntersections() 函数可以正常工作,但我从光线投射中获得了每一次命中,但我只想要 first 命中。

OpenMaya.MFnMesh API 的链接: 链接:https://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__py_ref_class_open_maya_1_1_m_fn_mesh_html

【问题讨论】:

    标签: python raycasting maya-api


    【解决方案1】:

    主要是anyIntersection 正在寻找它首先命中的单个 交叉点,而不是多个交叉点。所以你的输出参数是错误的类型,因为它们是数组。

    我也会避免在循环中清除或做出新的选择,因为每次都必须重新绘制视口会降低性能。

    这是一个工作示例,它将在它命中的第一个网格上创建一个定位器:

    import maya.OpenMaya as OpenMaya
    import maya.cmds as cmds
    
    
    def RayReposition(*args):
        direction = (0.0, -1, 0)
        sel = cmds.ls(sl=True)
    
        fromPositionRay = cmds.xform(sel[0], query=True, translation=True)
        selShape = cmds.listRelatives(shapes=True)
        meshes = cmds.ls(geometry=True)
    
        for x in meshes:
            if x == selShape[0]:
                continue
            else:
                sList = OpenMaya.MSelectionList()
                sList.add(x)
                item = OpenMaya.MDagPath()
                sList.getDagPath(0, item)
                item.extendToShape()
    
                fnMesh = OpenMaya.MFnMesh(item)
    
                raySource = OpenMaya.MFloatPoint(fromPositionRay[0], fromPositionRay[1], fromPositionRay[2], 1.0)
                rayDir = OpenMaya.MFloatVector(direction[0], direction[1], direction[2])
                worldSpace = OpenMaya.MSpace.kWorld
                maxParam = 999999
                testBothDirections = False
                faceIds = None
                triIds = None
                idsSorted = False
                accelParams = None
                sortHits = True
    
                hitPoints = OpenMaya.MFloatPoint()
                hitRayParams = None
                hitFaces = None
                hitTris = None
                hitBarys1 = None
                hitBarys2 = None
                tolerance = 0.0001
    
                hit = fnMesh.anyIntersection(
                    raySource, rayDir, faceIds, triIds, idsSorted, worldSpace, maxParam, testBothDirections, accelParams, 
                    hitPoints, hitRayParams, hitFaces, hitTris, hitBarys1, hitBarys2, tolerance)
    
                if hit:
                    firstHit = (hitPoints.x, hitPoints.y, hitPoints.z)
                    loc = cmds.spaceLocator()[0]
                    cmds.xform(loc, ws=True, t=firstHit)
                    print "Hit on {} at {}".format(x, firstHit)
                    break
    
    
    RayReposition()
    

    我发现c++ documentation 更清楚该方法对参数的期望。

    【讨论】:

      猜你喜欢
      • 2021-08-29
      • 2022-11-07
      • 1970-01-01
      • 2021-06-23
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 2016-05-08
      相关资源
      最近更新 更多