def buildMesh() :

  numVertices=4
  numFaces=1
  outputMesh = OpenMaya.MObject()
  points = OpenMaya.MFloatPointArray()
  faceConnects = OpenMaya.MIntArray()
  faceCounts = OpenMaya.MIntArray()
  p = OpenMaya.MFloatPoint(-1.0,0.0,-1.0)
  points.append(p)
  p = OpenMaya.MFloatPoint(-1.0,0.0,1.0)
  points.append(p)
  p = OpenMaya.MFloatPoint(1.0,0.0,1.0)
  points.append(p)
  p = OpenMaya.MFloatPoint(1.0,0.0,-1.0)
  points.append(p)
  faceConnects.append(0)
  faceConnects.append(1)
  faceConnects.append(2)
  faceConnects.append(3)
  faceCounts.append(4)

  meshFN = OpenMaya.MFnMesh()

  meshFN.create(points, [4],faceConnects)
  nodeName = meshFN.name()
  print(nodeName)
  cmds.sets(nodeName, add='initialShadingGroup')  
  cmds.select(nodeName)  
  meshFN.updateSurface()
def drawBoundingBox(box, color):
    min = om.MFloatPoint(box.min)
    max = om.MFloatPoint(box.max)

    glPushAttrib(GL_ALL_ATTRIB_BITS)

    glDisable(GL_LIGHTING)
    glColor3f(color.r, color.g, color.b)
    glBegin(GL_LINE_STRIP)
    glVertex3f(min.x, min.y, min.z)
    glVertex3f(max.x, min.y, min.z)
    glVertex3f(max.x, max.y, min.z)
    glVertex3f(min.x, max.y, min.z)
    glVertex3f(min.x, min.y, min.z)
    glVertex3f(min.x, min.y, max.z)
    glVertex3f(min.x, max.y, max.z)
    glVertex3f(min.x, max.y, min.z)
    glVertex3f(max.x, max.y, min.z)
    glVertex3f(max.x, max.y, max.z)
    glVertex3f(max.x, min.y, max.z)
    glVertex3f(max.x, min.y, min.z)
    glVertex3f(max.x, min.y, max.z)
    glVertex3f(min.x, min.y, max.z)
    glVertex3f(min.x, max.y, max.z)
    glVertex3f(max.x, max.y, max.z)
    glEnd()

    glPopAttrib()
Esempio n. 3
0
def intersect(mesh, point, ray):
    ''' This is probably some foundation for the yet-to-be surface follow stuff.
    '''
    fnMesh = OpenMaya.MFnMesh(pdil.capi.asMObject(mesh.getShape()).object())

    p = spaceLocator()
    p.t.set(point)
    p.setParent(mesh)

    objSpacePos = p.t.get()

    p.setTranslation(ray, space='world')

    objSpaceRay = p.t.get() - objSpacePos

    point = OpenMaya.MFloatPoint(objSpacePos)
    ray = OpenMaya.MFloatVector(objSpaceRay)
    res = fnMesh.allIntersections(point, ray, OpenMaya.MSpace.kObject, 50,
                                  False)

    # -> (hitPoints, hitRayParams, hitFaces, hitTriangles, hitBary1s, hitBary2s)

    if not len(res[0]):
        hits = []

    else:
        hits = []
        for hit in res[0]:
            p.t.set(hit.x, hit.y, hit.z)
            hits.append(p.getTranslation(space='world'))

    delete(p)

    return hits
Esempio n. 4
0
    def get_coord_on_drag(self, selected, ctx):
        vpX, vpY, _ = cmds.draggerContext(ctx, query=True, dragPoint=True)
        position = om.MPoint()  # 3D point with double-precision coordinates
        direction = om.MVector()  # 3D vector with double-precision coordinates

        omui.M3dView().active3dView().viewToWorld(
            int(vpX),
            int(vpY),
            position,  # world point
            direction)  # world vector

        for mesh in selected:
            selectionList = om.MSelectionList()
            selectionList.add(mesh)
            dagPath = selectionList.getDagPath(0)
            fnMesh = om.MFnMesh(dagPath)

            intersection = fnMesh.closestIntersection(
                om.MFloatPoint(position),  # raySource
                om.MFloatVector(direction),  # rayDirection
                om.MSpace.kWorld,  # space
                99999,  # maxParam
                True)  # testBothDirections

            hitPoint, hitRayParam, hitFace, hitTriangle, \
                hitBary1, hitBary2 = intersection

            x, y, z, _ = hitPoint

        return x, y, z
Esempio n. 5
0
    def _closestIntersection(self, dagPath, worldPt, worldVector):
        """Return the closest intersection data for the given mesh with
        the given point and vector.

        :param dagPath: The MDagPath of the mesh object.
        :type dagPath: om2.MDagPath
        :param worldPt: The world point of the ray to test for
                        intersection with.
        :type worldPt: om2.MPoint
        :param worldVector: The MVector of the intersection ray.
        :type worldVector: om2.MVector

        :return: The tuple with the intersection data:
                 hitPoint: The intersection point.
                 hitRayParam: The ray length to the intersection.
                 hitFace: The face index of the intersection.
                 hitTriangle: The relative index of the trangle.
                 hitBary1: First barycentric coordinate.
                 hitBary2: Second barycentric coordinate.
        :rtype: tuple(om2.MFloatPoint, float, int, int, float, float)
        """
        meshFn = om2.MFnMesh(dagPath)

        accelParams = om2.MMeshIsectAccelParams()
        accelParams = meshFn.autoUniformGridParams()

        return meshFn.closestIntersection(
            om2.MFloatPoint(worldPt),
            om2.MFloatVector(worldVector),
            om2.MSpace.kWorld,
            100000,  # maxParam
            True)
Esempio n. 6
0
def onPress():
    vpX, vpY, _ = cmds.draggerContext(context, query=True, dragPoint=True)
    pos = om.MPoint()
    dir = om.MVector()
    omui.M3dView().active3dView().viewToWorld(int(vpX), int(vpY), pos, dir)
    for mesh in cmds.ls(type='mesh'):
        selectionList = om.MSelectionList()
        selectionList.add(mesh)
        dagPath = selectionList.getDagPath(0)
        fnMesh = om.MFnMesh(dagPath)
        hit = fnMesh.allIntersections(om.MFloatPoint(pos),
                                      om.MFloatVector(dir), om.MSpace.kWorld,
                                      99999, False)
        if hit:
            try:
                hit1 = hit[0][0]
                hit2 = hit[0][1]
                mySel = cmds.ls(sl=True)[-1]
                pos = [(hit1[0] + hit2[0]) / 2, (hit1[1] + hit2[1]) / 2,
                       (hit1[2] + hit2[2]) / 2]
                cmds.setAttr(mySel + '.translate',
                             pos[0],
                             pos[1],
                             pos[2],
                             type='double3')
            except:
                pass
Esempio n. 7
0
 def getPointer(s):
     """
     Get intersection point on the mesh from the mouse click.
     """
     if s.meshes:
         try:
             # Grab screen co-ords
             viewX, viewY, viewZ = cmds.draggerContext(s.tool, q=True, dp=True)
             # Set up empty vectors
             position = om.MPoint()
             direction = om.MVector()
             # Convert 2D positions into 3D positions
             omui.M3dView().active3dView().viewToWorld(int(viewX), int(viewY), position, direction)
             # Check our meshes
             for mesh in s.meshes:
                 selection = om.MSelectionList()
                 selection.add(mesh)
                 dagPath = selection.getDagPath(0)
                 fnMesh = om.MFnMesh(dagPath)
                 # Shoot a ray and check for intersection
                 intersection = fnMesh.closestIntersection(om.MFloatPoint(position), om.MFloatVector(direction), om.MSpace.kWorld, 99999, False)
                 # hitPoint, hitRayParam, hitFace, hitTriangle, hitBary1, hitBary2 = intersection
                 if intersection and intersection[3] != -1:
                     return (mesh, intersection[2]) # hit mesh and face ID
         except RuntimeError:
             pass
Esempio n. 8
0
def intersectionAPI2():
    """
    Select two objects. the second shot a ray at its X axis over the first.
    return: id face collision
    """
    mSelList = OpenMaya.MGlobal.getActiveSelectionList()

    dagPath0 = mSelList.getDagPath(0)
    dagPath0.extendToShape()

    mfnMesh0 = OpenMaya.MFnMesh(dagPath0)

    dagPath1 = mSelList.getDagPath(1)
    mfnTransform = OpenMaya.MFnTransform(dagPath1)

    testBothDirections = False
    maxParamPtr = 9999999.0
    space = OpenMaya.MSpace.kWorld
    spaceVector = OpenMaya.MSpace.kTransform

    raySource = OpenMaya.MFloatPoint(mfnTransform.rotatePivot(space))
    # print raySource

    rayDirectionMatrix = mfnTransform.rotation(spaceVector).asMatrix()

    rayDirection = OpenMaya.MFloatVector(rayDirectionMatrix[0],
                                         rayDirectionMatrix[1],
                                         rayDirectionMatrix[2])
    # http://zoomy.net/2009/07/31/fastidious-python-shrub/
    hit = mfnMesh0.closestIntersection(raySource, rayDirection, space,
                                       maxParamPtr, testBothDirections)
    pm.select('%s.f[%s]' % (dagPath0, hit[2]))
    print(hit)
Esempio n. 9
0
 def getClosestHit(source, direction):
     nurbsHit = nurbsFn.intersect(om.MPoint(source),
                                  om.MVector(direction),
                                  om.MSpace.kWorld)
     if nurbsHit is None:
         return None
     return om.MFloatPoint(nurbsHit[0])
Esempio n. 10
0
def meshIntersect(edgeVertsCoord=None, mesh2Intersect=None):
    '''see if a given edge(2 verts) interesects with mesh2Intersect
    '''

    # see if given mesh or edgeVertsCoord intersects with target mesh or not
    mSelList = om.MSelectionList()
    mDagPath = om.MDagPath()

    targetMesh = "%s" % mesh2Intersect
    mSelList.add(targetMesh)
    targetDagP = mSelList.getDagPath(0)
    targetMfnSet = om.MFnMesh(targetDagP)

    edgeCount = len(edgeVertsCoord)
    hitCount = 0
    for coord in edgeVertsCoord:
        rayStartPos = om.MFloatPoint(coord[0])
        rayEndPos = om.MFloatPoint(coord[1])
        rayVec = om.MFloatVector(rayEndPos - rayStartPos)
        rayLen = rayVec.length()
        infoList = targetMfnSet.closestIntersection(rayStartPos, rayVec,
                                                    om.MSpace.kWorld, 999,
                                                    False)

        hitPos = infoList[0]
        hitParem = infoList[1]
        hitLen = om.MVector(hitPos - rayStartPos).length()

        if hitParem == 0:  # not even hit at all
            continue
        elif hitParem != 0:
            if hitLen <= rayLen:
                #print True
                return True  # once a function does return, it ends the function
            else:  # hit point is further than the length of the edge, not intersecting
                hitCount += 1

        if hitCount == edgeCount:
            #print hitCount,edgeCount
            #print "inside geo or target too small"
            return False

    #print hitCount,edgeCount
    #print False
    return False
Esempio n. 11
0
def utils_screenTo3dOffset(camMatrix, coords, ssOffset):
    coef = 0.1

    vTargetCam = coords - ompy.MFloatPoint(matrix_getRow(3, camMatrix))
    vOffset = matrix_getRow(0, camMatrix) * ssOffset.x * -1.0 + matrix_getRow(
        1, camMatrix) * ssOffset.y * -1.0

    vOffset *= vTargetCam.length() * -0.015

    return vOffset
Esempio n. 12
0
def dagPath_getAttrMFloatPointArray(objPath, Attr):
    out_value = []

    node = objPath.node()
    plug = ompy.MPlug(node, Attr)
    if (plug.isNull == False):
        if (plug.isArray == True):
            for i in range(0, plug.numElements()):
                dHandle = plug.elementByLogicalIndex(i).asMDataHandle()
                out_value.append(ompy.MFloatPoint(dHandle.asFloatVector()))
                plug.destructHandle(dHandle)

    return out_value
Esempio n. 13
0
 def click(s):
     try:
         # Grab mouse co-ords on screen
         viewX, viewY, viewZ = cmds.draggerContext(s.myTool,
                                                   q=True,
                                                   ap=True)
         position = om.MPoint()
         direction = om.MVector()
         # Convert 2D screen positions into 3D world positions
         omui.M3dView().active3dView().viewToWorld(int(viewX), int(viewY),
                                                   position, direction)
         sel = om.MSelectionList()
         sel.add(s.sel)
         dagPath = sel.getDagPath(0)
         fnMesh = om.MFnMesh(dagPath)
         intersection = fnMesh.closestIntersection(
             om.MFloatPoint(position), om.MFloatVector(direction),
             om.MSpace.kWorld, 99999, False)
         # Did our ray intersect with the object?
         if intersection:
             hitPoint, hitRayParam, hitFace, hitTriangle, hitBary1, hitBary2 = intersection
             if hitTriangle != -1:
                 # Grab Skin Cluster
                 skin = mel.eval("findRelatedSkinCluster %s" % s.sel)
                 if skin:
                     # Get Face points
                     cmds.select("%s.f[%s]" % (s.sel, hitFace))
                     face = cmds.polyInfo(fv=True)
                     # Get vertexes
                     verts = [
                         "%s.vtx[%s]" % (s.sel, v)
                         for v in findall(r"\s(\d+)\s", face[0])
                     ]
                     # Get Joints
                     cmds.select(verts, r=True)
                     joints = cmds.skinPercent(skin, q=True, t=None)
                     # Get weights
                     weights = sorted(
                         [(j, cmds.skinPercent(skin, t=j, q=True))
                          for j in joints],
                         key=lambda x: x[1],
                         reverse=True)
                     cmds.select(weights[0][0], r=True)
                 else:
                     print "No skin found"
         # Return to previous tool
         cmds.setToolTo(s.tool)
         cmds.refresh()
     except RuntimeError:
         print "There was an issue selecting the object."
Esempio n. 14
0
def inMesh(meshObj, positions, maxRes=100):
    '''{'del_path':'Polygons/QueryMesh/inMesh()ONLYSE',
'icon':':/polyMesh.png',
'usage':'\
meshObj = cmds.ls(sl=True)[-1]\\n\
objs = cmds.ls(sl=True)[:-1]\\n\
positions = []\\n\
for obj in objs:\\n\
    positions.append( cmds.getAttr(obj+".t")[0] )\\n\\n\
inMeshData = $fun(meshObj, positions )\\n\
inMeshObjs=[]\\n\
for obj in objs:\\n\
    if inMeshData[ objs.index(obj) ]:\\n\
        inMeshObjs.append( obj )\\n\
if inMeshObjs:\\n\
    cmds.select(inMeshObjs, r=True)\\n\
mel:\\n\
string $object = "pCube1";\\n\
vector $pos = <<0,0,0>>;\\n\
python("$fun(\""+$object+"\",["+$pos.x+"," +$pos.y+"," +$pos.z+"])");',
}
'''
    meshs = newom.MSelectionList()
    meshs.add(meshObj)
    meshDagPath = meshs.getDagPath(0)
    meshFn = newom.MFnMesh(meshDagPath)

    divSize = emfx_getVoxelSize(meshObj, maxRes)
    bbox = cmds.exactWorldBoundingBox(meshObj, ignoreInvisible=False)
    xDiv = math.fabs(bbox[3] - bbox[0]) / divSize
    yDiv = math.fabs(bbox[4] - bbox[1]) / divSize
    zDiv = math.fabs(bbox[5] - bbox[2]) / divSize

    meshAcceleration = meshFn.uniformGridParams(int(xDiv), int(yDiv),
                                                int(zDiv))

    whethers = []
    rayDirection = newom.MFloatVector(0, -1, 0)
    for pos in positions:
        hitPoints = meshFn.allIntersections(newom.MFloatPoint(pos),
                                            rayDirection,
                                            newom.MSpace.kWorld,
                                            9999.0,
                                            False,
                                            accelParams=meshAcceleration)[0]
        whethers.append(True if len(hitPoints) % 2 == 1 else False)
    meshFn.clearGlobalIntersectionAcceleratorInfo()

    return whethers
Esempio n. 15
0
def get_ray_mesh_intersection(mesh, direction=[0,-1 ,0], origin=[0,1,0]):
    direction_v = om.MFloatVector(direction[0],direction[1],direction[2])
    origin_p = om.MFloatPoint(origin[0],origin[1],origin[2])
    # return om.MVector(pnt1-pnt2).length()

    selectionList = om.MSelectionList()
    selectionList.add(mesh)
    nodeDagPath = selectionList.getDagPath(0)
    
    mfn = om.MFnMesh(nodeDagPath)

    intersection = mfn.closestIntersection(origin_p, direction_v, om.MSpace.kWorld, 99999999, False)


    #return intersection#list(intersection[0])[:-1]
    vector = list(intersection[0])[:-1]
    distance = maths.distanceBetween(origin, vector)
    return {'vector':vector, 'distance':distance}
Esempio n. 16
0
def rayMeshIntersect(mesh, pos, vector):
    '''

    Example:

    mover = cmds.ls(sl=1)[0]

    mesh = 'steel'

    pos = cmds.xform(mover, q=1, rp=1, ws=1)

    newPos = rayMeshIntersect(mesh, pos, -utils.getAxisWorldVectors(mover)[1])

    cmds.xform(mover, t=newPos, ws=1)

    '''

    nodePos = om2.MPoint(pos[0], pos[1], pos[2], 1.0)

    vector = om2.MVector(vector)

    obj, dag, stringPath = dagPathFromName(mesh)

    meshFn = om2.MFnMesh(dag)

    selectionList = om2.MSelectionList()

    selectionList.add(mesh)

    dagPath = selectionList.getDagPath(0)

    fnMesh = om2.MFnMesh(dagPath)

    intersection = fnMesh.closestIntersection(om2.MFloatPoint(pos),
                                              om2.MFloatVector(vector),
                                              om2.MSpace.kWorld, 99999, False)

    if intersection:

        hitPoint, hitRayParam, hitFace, hitTriangle, hitBary1, hitBary2 = intersection

        x, y, z, _ = hitPoint

        return (x, y, z)
Esempio n. 17
0
def checkHit():
    sel = om.MGlobal.getActiveSelectionList()
    mesh_fn = loc_fn = None
    if sel.length():
        mesh_dag = sel.getDagPath(0)
        if mesh_dag.hasFn(om.MFn.kMesh):
            mesh_fn = om.MFnMesh(mesh_dag)

    loc_dag = sel.getDagPath(1)
    if loc_dag.hasFn(om.MFn.kTransform):
        loc_fn = om.MFnTransform(loc_dag)

    print mesh_fn, loc_fn
    ray_src = om.MFloatPoint(loc_fn.translation(om.MSpace.kWorld))
    ray_dir = om.MFloatVector(0,0,1)
    hit_points = mesh_fn.allIntersections(ray_src, ray_dir, om.MSpace.kObject, 9999, False )
    for p in hit_points[0]:
        loc = pm.spaceLocator()
        pm.move(loc, [p[0], p[1], p[2]])
Esempio n. 18
0
def inflateMesh(mesh, scale=1):

    sel_list = om.MSelectionList()
    sel_list.add(str(mesh))

    DagPath, Obj = sel_list.getComponent(0)

    Mesh = om.MFnMesh(DagPath)
    MeshPoints = Mesh.getPoints(om.MSpace.kWorld)
    newMeshPoints = om.MFloatPointArray()

    for i in range(len(MeshPoints)):
        MeshPointNormal = Mesh.getVertexNormal(i, om.MSpace.kWorld)

        x = MeshPoints[i].x + MeshPointNormal.x * scale
        y = MeshPoints[i].y + MeshPointNormal.y * scale
        z = MeshPoints[i].z + MeshPointNormal.z * scale
        newMeshPoint = om.MFloatPoint(x, y, z)

        newMeshPoints.append(newMeshPoint)

    Mesh.setPoints(newMeshPoints, om.MSpace.kWorld)
Esempio n. 19
0
def rayIntersect(pos, dir, mesh):

    pos2 = om.MFloatPoint(pos.x, pos.y, pos.z)
    dir = om.MFloatVector(dir.x, dir.y, dir.z)

    selectionList = om.MSelectionList()
    selectionList.add(mesh)
    dagPath = om.MDagPath()
    sel = selectionList.getDagPath(0)
    fnMesh = om.MFnMesh(sel)

    intersection = fnMesh.closestIntersection(pos2, dir, om.MSpace.kWorld,
                                              9999, False)
    hitpoint = intersection[0]
    faceId = intersection[2]
    if intersection:
        x = hitpoint.x
        y = hitpoint.y
        z = hitpoint.z
        return x, y, z, faceId
    else:
        return None
Esempio n. 20
0
def positionsOnMesh(meshObj, position, rayDirection=False):
    '''{'del_path':'Polygons/QueryMesh/positionsOnMesh()ONLYSE',
'usage':'\
meshObj = cmds.ls(sl=True)[-1]\\n\
objs = cmds.ls(sl=True)[:-1]\\n\
position = []\\n\
for obj in objs:\\n\
    position.append( cmds.getAttr(obj+".t")[0] )\\n\
newPos = $fun(meshObj, position, rayDirection=(0,-1,0) )\\n\
for obj in objs:\\n\
    pos = newPos[ objs.index(obj) ]\\n\
    cmds.setAttr(obj+""t", pos[0], pos[1], pos[2], type="double3")',
}
'''
    meshs = newom.MSelectionList()
    meshs.add(meshObj)
    meshDagPath = meshs.getDagPath(0)
    meshFn = newom.MFnMesh(meshDagPath)

    newPos = []
    if rayDirection == False:
        print rayDirection
        for pos in position:
            newPos.append(
                tuple(
                    meshFn.getClosestPoint(newom.MPoint(pos),
                                           newom.MSpace.kWorld)[0]))
    else:
        rayDirection = newom.MFloatVector(rayDirection)
        for pos in position:
            raySource = newom.MFloatPoint(pos)
            hitPoint = tuple(
                meshFn.closestIntersection(raySource, rayDirection,
                                           newom.MSpace.kWorld, 9999.0,
                                           False)[0])
            hitPos = pos if hitPoint == (0, 0, 0, 1) else hitPoint
            newPos.append(hitPos)
    return newPos
Esempio n. 21
0
def create(verts, faces, merge=True):
    '''
	Given a list of vertices (iterables of floats) and a list of faces (iterable of integer vert indices),
	creates and returns a maya Mesh
	'''

    cmds.select(cl=True)
    outputMesh = OpenMaya.MObject()

    # point array of mesh vertex local positions
    points = OpenMaya.MFloatPointArray()
    for eachVt in verts:
        p = OpenMaya.MFloatPoint(eachVt[0], eachVt[1], eachVt[2])
        points.append(p)

    # vertex connections per poly face in one array of indexs into point array given above
    faceConnects = OpenMaya.MIntArray()
    for eachFace in faces:
        for eachCorner in eachFace:
            faceConnects.append(int(eachCorner))

    # an array to hold the total number of vertices that each face has in this case quads so 4
    faceCounts = OpenMaya.MIntArray()
    # python lists can be multiplied to duplicate
    faceCounts = [4] * len(faces)
    # get a mesh function set
    meshFN = OpenMaya.MFnMesh()
    # create mesh object using arrays above
    meshFN.create(points, faceCounts, faceConnects, parent=outputMesh)
    # now grab the name of the mesh
    nodeName = meshFN.name()
    cmds.sets(nodeName, add='initialShadingGroup')
    cmds.select(nodeName)
    meshFN.updateSurface()
    # this is useful because it deletes stray vertices (ie, those not used in any faces)
    cmds.polyMergeVertex(nodeName, ch=0)
    meshFN.updateSurface()
    return nodeName
Esempio n. 22
0
	def computeShapeOffset( rbT, bboxPos=[0.0,0.0,0.0], comPos=[0.0,0.0,0.0] ):
		# We want the implicit collision shapes (box etc) to 
		# centered around the bounding box center so, we need to make
		# the collider shift offset relative to the center of mass
		rtn = (bboxPos[0]-comPos[0]), (bboxPos[1]-comPos[1]), (bboxPos[2]-comPos[2])

		scl = maya.cmds.xform(rbT, q=True, relative=True, scale=True)

		# if scaling applied then remove
		if scl[0]!=1.0 or scl[1]!=1.0 or scl[2]!=1.0:
			m = [
				scl[0],	0.0,	0.0,	0.0,
				0.0,	scl[1],	0.0,	0.0,
				0.0,	0.0,	scl[2],	0.0,
				0.0,	0.0,	0.0,	1.0 ]

			pt = OpenMaya.MFloatPoint(rtn)
			sclMat = OpenMaya.MFloatMatrix(m)

			# return x,y,z
			rtn = list(pt * sclMat.inverse())[:-1]

		return rtn
Esempio n. 23
0
def test_mesh_intersection(current_mesh, target_mesh):
    # get intersection bbox
    inter_bbox = get_inter_bbox(current_mesh.boundingBox(),
                                target_mesh.boundingBox())
    # check if edge of current mesh intersect to face of target mesh
    all_hit_faces = []
    all_hit_points = []
    for edge in target_mesh.edges:
        sour_point = om.MPoint(edge.getPoint(0, 'world'))
        end_point = om.MPoint(edge.getPoint(1, 'world'))
        # ignore edge not in inter bbox
        if not (inter_bbox.contains(sour_point)
                or inter_bbox.contains(end_point)):
            continue
        # do test

        current_mesh_om = om.MFnMesh(pynode_to_api2(current_mesh))
        edge_vector = end_point - sour_point
        edge_len = edge_vector.length()
        edge_vector.normalize()
        speedup_param = current_mesh_om.autoUniformGridParams()
        hitPoints, _, hit_faces, _, _, _ = current_mesh_om.allIntersections(
            om.MFloatPoint(sour_point),  # 射线起点
            om.MFloatVector(edge_vector),  # 射线方向
            om.MSpace.kWorld,  # 世界空间
            edge_len,  # 测试距离,超出此距离的命中不算
            False,  # 不进行双向测试
            accelParams=speedup_param  # 加速参数
        )

        all_hit_points.extend(hitPoints)
        all_hit_faces.extend(
            [current_mesh.f[face_id] for face_id in hit_faces])

    # TODO locator 生成位置不对
    # [pm.spaceLocator(p=(pt.x,pt.y,pt.z)) for pt in all_hit_points]
    return all_hit_faces
Esempio n. 24
0
def _mesh_to_ray_intersection(ray,
                              mesh,
                              both_dirs=True,
                              clean_up=True,
                              above_only=True):
    """Calculate ray/mesh intersections.

    Args:
        ray (HVRay): ray object
        mesh (HFnMehs): mesh object
        both_dirs (bool): check intersections in both directions (ie. if
            this if false then intersections coming out of faces will not
            be flagged)
        clean_up (bool): remove duplicate points - these can occur if a ray
        intersects an the edge between two faces
        above_only (bool): remove points behind the ray's start point

    Returns:
        (HPoint list): list of points
    """
    from maya_psyhive import open_maya as hom

    _ray_src = om.MFloatPoint(*ray.pnt.to_tuple())
    _ray_dir = om.MFloatVector(*ray.vec.to_tuple())
    _space = om.MSpace.kWorld
    _max_param = 999999

    _result = mesh.allIntersections(
        _ray_src,
        _ray_dir,
        _space,
        _max_param,
        both_dirs,
    )

    # Convert to HPoints
    _pts = []
    for _item in _result[0]:
        _pt = hom.HPoint(_item)
        _pts.append(_pt)

    lprint('FOUND {:d} PTS'.format(len(_pts)), _pts, verbose=0)

    # Remove duplicate points
    if clean_up:
        _clean_pts = []
        while _pts:
            _clean_pts.append(_pts.pop())
            for _pt in copy.copy(_pts):
                for _clean_pt in _clean_pts:
                    if not (_pt - _clean_pt).length():
                        _pts.remove(_pt)
        _pts = _clean_pts

    # Remove points behind the ray's start point
    if above_only:
        _above_pts = []
        _plane = ray.to_plane()
        for _pt in _pts:
            _dist = _plane.distanceToPoint(hom.HVector(_pt), signed=True)
            if _dist > 0.0001:
                _above_pts.append(_pt)
        _pts = _above_pts

    return _pts
Esempio n. 25
0
def curveEditPointsOnMesh(*args, **kwargs):
    '''{'path':'Dynamics/Particles/Crowd/curveEditPointsOnMesh( )',
'icon':':/curveCV.png',
'tip':'把曲线吸附到多边形上',
'usage':"""
#选择曲线,再选择mesh;当closest=False,曲线按垂直方向投射到mesh上,为True,投射到最终的mesh的位置上
$fun( closest=False )"""
}
'''
    if len(args) > 1:
        nurCurves = args[0]
        if type(nurCurves) == type(''):
            nurCurve = (nurCurves, )
        mesh = args[1]
    else:
        sel = cmds.ls(sl=True)
        if len(sel) > 1:
            nurCurves, mesh = sel[:-1], sel[-1]
        else:
            print 'Select two objects or assign arguments to the function!'
            return False

    mesh = checkArg(mesh, nodeType='mesh')
    if not mesh:
        print 'Least object is not mesh'
        return False

    closest = kwargs.get('closest', False)

    for nurCurve in nurCurves:
        nurCurve = checkArg(nurCurve, nodeType='nurbsCurve')

        if not nurCurve:
            print '%s is not nurbsCurve object' % (nurCurve)
            continue

        curveNode = nameToNode(nurCurve, old=True)
        curFn = om.MFnNurbsCurve(curveNode)
        numEPs = curFn.numCVs() - curFn.degree() + 1

        meshNode = nameToNode(mesh)
        meshFn = newom.MFnMesh(meshNode)

        #print closest
        for i in range(numEPs):
            ep = '%s.ep[%s]' % (nurCurve, i)
            pos = newom.MPoint(cmds.pointPosition(ep))

            meshPoint = meshFn.closestIntersection(newom.MFloatPoint(pos),
                                                   newom.MFloatVector(0, 1, 0),
                                                   newom.MSpace.kWorld, 9999.0,
                                                   True)
            if meshPoint[2] != -1:
                #print meshPoint
                dis = (meshPoint[0][0] - pos[0], meshPoint[0][1] - pos[1],
                       meshPoint[0][2] - pos[2])
                cmds.move(dis[0], dis[1], dis[2], ep, r=True)
            elif closest == True:
                closestPoint = meshFn.getClosestPoint(pos, newom.MSpace.kWorld)
                dis = (closestPoint[0][0] - pos[0],
                       closestPoint[0][1] - pos[1],
                       closestPoint[0][2] - pos[2])
                cmds.move(dis[0], dis[1], dis[2], ep, r=True)
Esempio n. 26
0
    def getVoxels(self, pVoxelDistance, pMeshObj, pBoundingBox):
        '''
        Obtain a list of voxels as a set of (x,y,z) coordinates in the mesh local space.

        We obtain these voxels by casting rays from points separated pVoxelDistance apart within the
        mesh bounding box, and test whether or not these points are contained within the mesh.

        A point is contained within a closed mesh if the ray shot from the point intersects an odd
        number of times with the surface of the mesh.
        '''
        # Initialize a list of voxels contained within the mesh.
        voxels = []

        # Get a reference to the MFnMesh function set, and use it on the given mesh object.
        meshFn = OpenMaya.MFnMesh(pMeshObj)

        # Compute an offset which we will apply to the min and max corners of the bounding box.
        halfVoxelDist = 0.5 * pVoxelDistance

        # Offset the position of the minimum point to account for the inter-voxel distance.
        minPoint = pBoundingBox.min
        minPoint.x += halfVoxelDist
        minPoint.y += halfVoxelDist
        minPoint.z += halfVoxelDist

        # Offset the position of the maximum point to account for the inter-voxel distance.
        maxPoint = pBoundingBox.max
        maxPoint.x += halfVoxelDist
        maxPoint.y += halfVoxelDist
        maxPoint.z += halfVoxelDist

        # Define an iterator which will allow us to step through the pVoxelDistance
        # point intervals contained within our bounding box. We use this iterator
        # in the for loops that follow to visit each voxel center in the bounding box.
        def floatIterator(start, stop, step):
            r = start
            while r < stop:
                yield r
                r += step

        # Iterate over every point in the bounding box, stepping by pVoxelDistance...
        for xCoord in floatIterator(minPoint.x, maxPoint.x, pVoxelDistance):
            for yCoord in floatIterator(minPoint.y, maxPoint.y,
                                        pVoxelDistance):
                for zCoord in floatIterator(minPoint.z, maxPoint.z,
                                            pVoxelDistance):

                    # 2D representation of a ray cast from the point within the bounding box:
                    #
                    #  (+) ^-----------------
                    #      |                |
                    #  y   |                |  - We are shooting the ray from the point: [*]
                    # axis | <======[*]     |  - The direction of the ray is parallel to the -Z axis.
                    #      |                |
                    #      |                |
                    #  (-) ------------------>
                    #     (-)    z axis     (+)
                    #
                    # If the ray intersects with an odd number of points along the surface of the mesh, the
                    # point is contained within the mesh (assuming a closed mesh).
                    raySource = OpenMaya.MFloatPoint(xCoord, yCoord, zCoord)
                    rayDirection = OpenMaya.MFloatVector(0, 0, -1)
                    # intersectionPoints = OpenMaya.MFloatPointArray()
                    tolerance = 0.0001

                    ret = meshFn.allIntersections(
                        raySource,  # raySource - where we are shooting the ray from.
                        rayDirection,
                        # rayDirection - the direction in which we are shooting the ray.
                        OpenMaya.MSpace.kTransform,
                        # coordinate space - the mesh's local coordinate space.
                        float(9999),  # maxParam - the range of the ray.
                        False,
                        # testBothDirections - we are not checking both directions from the raySource
                        tolerance=tolerance,
                        # tolerance - a numeric tolerance threshold which allow intersections to occur just outside the mesh.
                    )

                    # Returns a tuple of:
                    # -> (hitPoints, hitRayParams, hitFaces, hitTriangles, hitBary1s, hitBary2s)

                    # If there is an odd number of intersection points, then the point lies within the mesh. Otherwise,
                    # the point lies outside the mesh. We are only concerned with voxels whose centerpoint lies within the mesh
                    if (len(ret[0]) % 2 == 1):
                        voxels.append(raySource)

        # Return the list of voxel coordinates which lie within the mesh.
        return voxels
Esempio n. 27
0
    def setPointFromVolume(self, distance, surface=False, rand=False):
        """
        mesh にポイントを散布し、そのポイントのポジション情報を取得
        引数:
            distance(float) : ポイント間の距離。値が小さいほど密度が濃い
            surface(bool)   : True の場合、メッシュの表面に散布
            rand(float)     : random に配置。数値がそのままランダム強度値となる
        """

        # 境界ボックスの最小角と最大角に適用するオフセットを計算
        self.halfVoxelDist = 0.5 * distance
        # バウンディングボックスの最小値を取得
        self.minPoint = self.getBoundingBox().min
        self.minPoint.x += self.halfVoxelDist
        self.minPoint.y += self.halfVoxelDist
        self.minPoint.z += self.halfVoxelDist
        # バウンディングボックスの最大値を取得
        self.maxPoint = self.getBoundingBox().max
        self.maxPoint.x += self.halfVoxelDist
        self.maxPoint.y += self.halfVoxelDist
        self.maxPoint.z += self.halfVoxelDist

        def floatIterator(start, stop, step):
            """
            start ~ stop 範囲内の数値で step で指定した数分繰り返し、計算値を格納
            例)
                バウンディングボックスの最小値(start) ~ 最大値(stop) の間で指定した数(step) の均等なポジション情報を取得。
            """
            r = start
            while r < stop:
                yield r
                r += step

        # 計算後のポジション情報を宣言
        self.voxels = []
        for xCoord in floatIterator(self.minPoint.x, self.maxPoint.x,
                                    distance):
            for yCoord in floatIterator(self.minPoint.y, self.maxPoint.y,
                                        distance):
                for zCoord in floatIterator(self.minPoint.z, self.maxPoint.z,
                                            distance):

                    # 交差判定のパラメータ
                    self.raySource = om.MFloatPoint(xCoord, yCoord, zCoord)
                    self.maxParam = 9999.0
                    self.tolerance = 0.0001
                    randX = random.uniform(-1, 1) * rand
                    randY = random.uniform(-1, 1) * rand
                    randZ = random.uniform(-1, 1) * rand

                    # 引数設定時の分岐
                    if surface == True:
                        if rand != False:
                            self.raySource += om.MFloatPoint(
                                randX, randY, randZ)
                            self.rayDirection = om.MFloatVector(
                                randX, randY, randZ)
                        elif rand == False:
                            rand = 1
                            self.raySource += om.MFloatPoint(
                                randX, randY, randZ)
                            self.rayDirection = om.MFloatVector(
                                randX, randY, randZ)
                    elif surface == False:
                        if rand != False:
                            self.raySource += om.MFloatPoint(
                                randX, randY, randZ)
                            self.rayDirection = om.MFloatVector(
                                randX, randY, randZ)
                        elif rand == False:
                            self.rayDirection = om.MFloatVector(0, 0, -1)

                    # 交差判定
                    self.ret = self.meshFn.allIntersections(
                        self.raySource,  # raySource ---------- レイスタートポイント
                        self.rayDirection,  # rayDirection ------- レイの方向
                        om.MSpace.
                        kWorld,  # coordinate space --- ヒットポイントが指定されている座標空間
                        self.maxParam,  # maxParam ----------- ヒットを考慮する最大半径
                        False,  # testBothDirections - 負のrayDirectionのヒットも考慮する必要があるかどうか
                        tolerance=self.
                        tolerance,  # tolerance ---------- 交差操作の数値許容差
                    )

                    # 引数設定時の戻り値の分岐
                    if surface == True:
                        if (len(self.ret[0]) % 2 == 1):
                            self.voxels.append(
                                (self.ret[0][0][0], self.ret[0][0][1],
                                 self.ret[0][0][2]))
                        elif len(self.ret[0]) % 2 == 0 and len(
                                self.ret[0]) != 0:
                            self.voxels.append(
                                (self.ret[0][0][0], self.ret[0][0][1],
                                 self.ret[0][0][2]))

                    elif surface == False:
                        # 飛ばしたレイが1回のみ当たった場合はメッシュの中、それ以外はメッシュの外と判定
                        if (len(self.ret[0]) % 2 == 1):
                            self.voxels.append(self.raySource)

        return self.voxels
Esempio n. 28
0
import pymel.core as pmc
import pymel.core.datatypes as pmdt
import maya.api.OpenMaya as OpenMaya

vertexArray = OpenMaya.MFloatPointArray()
v = OpenMaya.MFloatPoint(0.0, 0.0, 0.0)
vertexArray.append(v)
v = OpenMaya.MFloatPoint(0.0, 1.0, 0.0)
vertexArray.append(v)
v = OpenMaya.MFloatPoint(1.0, 1.0, 0.0)
vertexArray.append(v)
v = OpenMaya.MFloatPoint(1.0, 0.0, 0.0)
vertexArray.append(v)
v = OpenMaya.MFloatPoint(2.0, 1.0, 0.0)
vertexArray.append(v)
v = OpenMaya.MFloatPoint(2.0, 0.0, 0.0)
vertexArray.append(v)

polygonCounts = OpenMaya.MIntArray()
polygonCounts.append(3)
polygonCounts.append(3)
polygonCounts.append(3)
polygonCounts.append(3)

polygonConnects = OpenMaya.MIntArray()
polygonConnects.append(0)
polygonConnects.append(2)
polygonConnects.append(1)
polygonConnects.append(0)
polygonConnects.append(3)
polygonConnects.append(2)
Esempio n. 29
0
def read_skc_file(scale_rate, skc_path, mesh_name):
    file = open(skc_path, "r")

    line = file.readline()

    vertexArray = OpenMaya.MFloatPointArray()
    uArray = OpenMaya.MFloatArray()
    vArray = OpenMaya.MFloatArray()

    polygonCounts = OpenMaya.MIntArray()
    polygonConnects = OpenMaya.MIntArray()

    vertexWeights = []

    material_num = 0
    material_sets = []

    while True:
        line = file.readline()
        if not line:
            break

        line = strip_space_line(line)

        if line.find("Materials") != -1:
            line = strip_space_line(line)
            material_num = int(line.split(":")[1])
            for i in range(0, int(material_num)):
                material_sets.append(0)
        elif line.find("Vertices") != -1:
            print line
        elif line[0] == "v":
            vertex_data = parse_pos_uv_weight(line)
            pos = vertex_data[0]
            pos[0] *= scale_rate
            pos[1] *= scale_rate
            pos[2] *= scale_rate
            v = OpenMaya.MFloatPoint(pos[0], pos[1], pos[2])
            vertexArray.append(v)

            uv = vertex_data[1]
            uArray.append(uv[0])
            vArray.append(uv[1])

            # bone weights
            skin_data = vertex_data[2]
            weight_num = skin_data[0]
            weights = []
            for bi in range(0, int(weight_num)):
                tmp_bone_idx = skin_data[int(1 + 2 * bi)]
                tmp_bone_name = bone_name_list[int(tmp_bone_idx)]
                tmp_bone_weight = skin_data[int(2 + 2 * bi)]
                key_value = (tmp_bone_name, tmp_bone_weight)
                weights.append(key_value)
            vertexWeights.append(weights)

        elif line.find("Triangles") != -1:
            print line
        elif line[0] == "f":
            face_data = parse_face(line)
            polygonCounts.append(3)

            polygonConnects.append(int(face_data[2]))
            polygonConnects.append(int(face_data[3]))
            polygonConnects.append(int(face_data[4]))

            # assign material
            material_sets[int(face_data[1])] += 1

    mFn_Mesh = OpenMaya.MFnMesh()
    m_DagMod = OpenMaya.MDagModifier()
    new_object = m_DagMod.createNode('transform')

    mFn_Mesh.create(vertexArray, polygonCounts, polygonConnects, uArray,
                    vArray, new_object)
    mFn_Mesh.setName(mesh_name)
    m_DagMod.doIt()

    new_mesh = pmc.PyNode(mesh_name)
    new_transform = pmc.listRelatives(new_mesh, type='transform',
                                      parent=True)[0]

    mFn_Mesh.assignUVs(polygonCounts, polygonConnects, 'map1')

    node_name = mesh_name + "_mesh"

    pmc.select(new_transform)
    pmc.rename(new_transform, node_name)

    # skin cluster
    pmc.select(bone_name_list[0], add=True)
    skin_cluster = pmc.skinCluster(bindMethod=0,
                                   skinMethod=1,
                                   normalizeWeights=0,
                                   maximumInfluences=4,
                                   obeyMaxInfluences=True)
    pmc.select(node_name, r=True)
    pmc.skinPercent(skin_cluster, node_name, normalize=False, pruneWeights=100)

    for v in range(0, len(vertexWeights)):
        pmc.skinPercent(skin_cluster,
                        "{0}.vtx[{1}]".format(node_name, v),
                        transformValue=vertexWeights[v],
                        normalize=True)

    #create material
    #pCylinder1.f[14:17] _mesh.f[{0}:{1}].format()

    material_starts = []
    material_ends = []
    mesh_selcte_sets = []

    material_sets = filter(lambda x: x != 0, material_sets)
    print material_sets

    material_starts.append(0)
    material_ends.append(material_sets[0] - 1)
    mesh_selcte_sets.append(
        node_name +
        ".f[{0}:{1}]".format(int(material_starts[0]), int(material_ends[0])))
    for i in range(1, len(material_sets)):
        material_starts.append(material_ends[int(i - 1)] + 1)
        material_ends.append(material_ends[int(i - 1)] + material_sets[i])
        mesh_selcte_sets.append(node_name + ".f[{0}:{1}]".format(
            int(material_starts[i]), int(material_ends[i])))

    print mesh_selcte_sets

    # 没有这一句会出错,必须将以前的选择清理掉
    pmc.select(clear=True)

    for i in range(0, len(mesh_selcte_sets)):
        shader_name = "p_shader{0}".format(int(i))
        new_shader = pmc.shadingNode("lambert",
                                     asShader=True,
                                     name=shader_name)
        new_shadinggroup = pmc.sets(renderable=True,
                                    noSurfaceShader=True,
                                    empty=True,
                                    name='{}_SG'.format(shader_name))
        pmc.connectAttr(new_shader.outColor, new_shadinggroup.surfaceShader)

        pmc.select(mesh_selcte_sets[i])
        pmc.hyperShade(assign=new_shadinggroup)
        pmc.select(clear=True)
Esempio n. 30
0
def read_gmc_data(scale_rate, gmc_path, mesh_name):
    # first read, get object section
    file = open(gmc_path, "r")

    line_num = -1
    line_nums = []

    line = file.readline()
    line_num += 1

    while True:
        line = file.readline()
        line_num += 1

        if not line:
            break

        line = strip_space_line(line)
        if line.find("Object") == 0:
            line_nums.append(line_num)

    print line_nums

    file.close()

    # second read,read section 1
    vertexArray = OpenMaya.MFloatPointArray()
    uArray = OpenMaya.MFloatArray()
    vArray = OpenMaya.MFloatArray()

    polygonCounts = OpenMaya.MIntArray()
    polygonConnects = OpenMaya.MIntArray()

    material_num = 0
    material_sets = []

    file = open(gmc_path, "r")
    line_num = -1

    line = file.readline()
    line_num += 1

    while True:
        line = file.readline()
        line_num += 1

        if not line:
            break

        line = strip_space_line(line)
        if line_num >= line_nums[0] and line_num < line_nums[1]:

            if line.find("Vertices") == 0:
                print line
            elif line.find("v") == 0:
                vertex_line = re.split("v|n|c|t", line)
                vertex_data = []
                vertex_data.append(parse_mesh_element(vertex_line[1]))
                vertex_data.append(parse_mesh_element(vertex_line[4]))

                pos = vertex_data[0]
                pos[0] *= scale_rate
                pos[1] *= scale_rate
                pos[2] *= scale_rate

                v = OpenMaya.MFloatPoint(pos[0], pos[1], pos[2])
                vertexArray.append(v)

                uv = vertex_data[1]
                uArray.append(uv[0])
                vArray.append(uv[1])

            elif line.find("f") == 0:
                face_line = line[1:]
                face_data = []
                face_data = parse_mesh_element(face_line)

                print face_data

                polygonCounts.append(3)

                polygonConnects.append(int(face_data[1]))
                polygonConnects.append(int(face_data[2]))
                polygonConnects.append(int(face_data[3]))

    mFn_Mesh = OpenMaya.MFnMesh()
    m_DagMod = OpenMaya.MDagModifier()
    new_object = m_DagMod.createNode('transform')

    mFn_Mesh.create(vertexArray, polygonCounts, polygonConnects, uArray,
                    vArray, new_object)
    mFn_Mesh.setName(mesh_name)
    m_DagMod.doIt()

    new_mesh = pmc.PyNode(mesh_name)
    new_transform = pmc.listRelatives(new_mesh, type='transform',
                                      parent=True)[0]

    mFn_Mesh.assignUVs(polygonCounts, polygonConnects, 'map1')

    node_name = mesh_name + "_mesh"

    pmc.select(new_transform)
    pmc.rename(new_transform, node_name)

    file.close()