Esempio n. 1
0
    def compute(self,plug,dataBlock):

        if plug == fakeSpring.outputA or plug == fakeSpring.outputB:

            start = dataBlock.inputValue(fakeSpring.start).asFloat3()
            startPos = om.MVector(start)

            end = dataBlock.inputValue(fakeSpring.end).asFloat3()
            endPos = om.MVector(end)

            stiffness = dataBlock.inputValue(fakeSpring.stiffness).asFloat()
            length = dataBlock.inputValue(fakeSpring.length).asFloat()


            directionalVector = endPos - startPos

            offset = (directionalVector.length() - length)/2.0
            scalor = (offset / directionalVector.length()) * stiffness

            outputAPos = startPos + (directionalVector * scalor)
            outputBPos = endPos - (directionalVector * scalor)


            outputA = dataBlock.outputValue(fakeSpring.outputA)
            outputAPosition = om.MFloatVector(outputAPos.x, outputAPos.y, outputAPos.z)
            outputA.setMFloatVector(outputAPosition)
            outputA.setClean()

            outputB = dataBlock.outputValue(fakeSpring.outputB)
            outputBPosition = om.MFloatVector(outputBPos.x, outputBPos.y, outputBPos.z)
            outputB.setMFloatVector(outputBPosition)
            outputB.setClean()

            dataBlock.setClean(plug)
Esempio n. 2
0
    def calculateNewNormal(self, v):
        """
        :type v: components.Vertex
        """
        polySets = []

        for polygon in v.polygons:
            ps = components.PolySet(polygon)
            ps.addPolygons(self.getGrownPolygons(polygon))
            polySets.append(ps)

        numPolySets = len(polySets)
        if numPolySets == 1:
            return om.MFloatVector(polySets[0].normal)

        polySets.sort(key=operator.attrgetter('area'), reverse=True)

        if numPolySets == 2:
            if polySets[0] == polySets[1]:
                return om.MFloatVector(
                    com.vectorsMean(polySets[0].normal, polySets[1].normal))
            else:
                return om.MFloatVector(polySets[0].normal)

        midArea = polySets[0].area - (polySets[0].area -
                                      polySets[-1].area) * 0.5
        masterNormals = [ps.normal for ps in polySets if ps.area >= midArea]
        return om.MFloatVector(com.vectorsMean(*masterNormals))
 def vectorCalc(vec, matrix):
     if (not isinstance(matrix, om.MMatrix)):
         return vec
     vm = om.MMatrix([[vec.x, 0, 0, 1], [0, vec.y, 0, 1], [0, 0, vec.z, 1],
                      [0, 0, 0, 1]])
     res = vm * matrix
     result = om.MFloatVector(res.getElement(0, 0), res.getElement(1, 1),
                              res.getElement(2, 2))
     return om.MFloatVector(result)
Esempio n. 4
0
    def __init__(self):
        om.MPxNode.__init__(self)

        self._initialize = False
        self._currentPosition = om.MFloatVector()
        self._previousPosition = om.MFloatVector()

        self._currentTime = om.MObject()
        self._previousTime = om.MObject()
Esempio n. 5
0
 def expand_to(self, data, n, setRandom=False):
     if len(data) >= n:
         return
     old_size = len(data)
     add_size = n - old_size
     for i in range(add_size):
         if not setRandom:
             data.append(om.MFloatVector(0.0, 0.0, 0.0))
         else:
             x = random.uniform(-1.0, 1.0)
             y = random.uniform(-1.0, 1.0)
             z = random.uniform(-1.0, 1.0)
             data.append(om.MFloatVector(x, y, z))
Esempio n. 6
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. 7
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. 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 convertToPointOnProjPlane(pointO, point, v2X, v2Y, distance):

    vectorTmp = ompy.MFloatVector(point.x - pointO.x, point.y - pointO.y,
                                  point.z - pointO.z)
    vectorTmp.normalize()
    pointTmp = pointO + vectorTmp * distance

    planeCoords = [
        pointTmp.x, pointTmp.y, pointTmp.z, pointTmp.x + v2X.x,
        pointTmp.y + v2X.y, pointTmp.z + v2X.z, pointTmp.x + v2Y.x,
        pointTmp.y + v2Y.y, pointTmp.z + v2Y.z
    ]
    lineCoords = [pointO.x, pointO.y, pointO.z, point.x, point.y, point.z]
    iPoint = utils_getLinePlaneIntersectionPoint(lineCoords, planeCoords)

    return ompy.MFloatVector(iPoint[0], iPoint[1], iPoint[2])
Esempio n. 10
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. 11
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. 12
0
def getLightDirection(name):
    selList = oom.MSelectionList()
    selList.add(name)

    lightDagPath = oom.MDagPath()
    selList.getDagPath(0, lightDagPath)

    lightFn = oom.MFnSpotLight(lightDagPath)

    rayDir = lightFn.lightDirection(0, oom.MSpace.kWorld)

    return om.MFloatVector(rayDir)
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 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. 16
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. 17
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. 18
0
    def reader(self, fileObject, optionString, accessMode):
        drc = Draco()
        mesh = drc.decode(fileObject.fullName())

        # vertices, normals, uvs
        vertices = []
        normals = []
        us = OpenMaya.MFloatArray()
        vs = OpenMaya.MFloatArray()
        poly_count = [3] * mesh.faces_num
        for n in range(mesh.vertices_num):
            i = 3 * n
            vertices.append(
                OpenMaya.MPoint(mesh.vertices[i], mesh.vertices[i + 1],
                                mesh.vertices[i + 2]))
            if mesh.normals:
                normals.append(
                    OpenMaya.MFloatVector(mesh.normals[i], mesh.normals[i + 1],
                                          mesh.normals[i + 2]))
            if mesh.uvs:
                i = 2 * n
                us.append(mesh.uvs[i])
                vs.append(mesh.uvs[i + 1])

        #create mesh
        fnMesh = OpenMaya.MFnMesh()
        newMesh = fnMesh.create(vertices, poly_count, mesh.faces)

        if mesh.normals:
            fnMesh.setVertexNormals(normals, range(len(vertices)))
        if mesh.uvs:
            uvSetsNames = fnMesh.getUVSetNames()
            fnMesh.setUVs(us, vs, uvSetsNames[0])
            fnMesh.assignUVs(poly_count, mesh.faces)

        fnMesh.updateSurface()

        slist = OpenMaya.MGlobal.getSelectionListByName("initialShadingGroup")
        initialSG = slist.getDependNode(0)

        fnSG = OpenMaya.MFnSet(initialSG)
        if fnSG.restriction() == OpenMaya.MFnSet.kRenderableOnly:
            fnSG.addMember(newMesh)
Esempio n. 19
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. 20
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. 21
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. 22
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. 23
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. 24
0
    def doIt(self,args):
        """
        The doIt method should collect whatever information is required to do the task, and store it in local class data. 
        It should finally call redoIt to make the command happen. 
        """
        self.parseArguments(args)
        
        # GET Joint DATA
        jointFn=om.MFnDagNode(self.Joint_dagPath)
        if jointFn.childCount()==1:
            next_joint_obj=jointFn.child(0)
        elif jointFn.childCount()>1:# Belly, Neck
            for i in range(jointFn.childCount()):
                tmpObj=jointFn.child(i)
                tmpFn=om.MFnDagNode(tmpObj)
                tmpName=tmpFn.name()
                if ("Chest" in tmpName) or ("Head" in tmpName):
                    next_joint_obj=jointFn.child(i)
        elif jointFn.childCount()==0 and jointFn.parentCount()==1:# Hip Hand Toe Top
            next_joint_obj=jointFn.parent(0)
            
        nextJointFn=om.MFnDagNode(next_joint_obj)
        self.nextJoint_dagPath = nextJointFn.getPath()
        self.nextJoint_name=nextJointFn.name()
                       
        # To avoid issues like freezeTransform, recommend rotate pivot to attain the position
        joint_position=cmds.xform(self.joint_name,absolute=True,query=True,worldSpace=True,rotatePivot=True)
        joint_position=om.MVector(joint_position[0],joint_position[1],joint_position[2])
        nextjoint_position=cmds.xform(self.nextJoint_name,absolute=True,query=True,worldSpace=True,rotatePivot=True)
        nextjoint_position=om.MVector(nextjoint_position[0],nextjoint_position[1],nextjoint_position[2])
        ray_center=linear_interpolate_3D(joint_position,nextjoint_position,self.u_parameter)                
       
       # GET THE LOCAL FRAME ON THE CHOOSEN JOINT
        VAxis=(joint_position-nextjoint_position).normalize()
        if VAxis.y<0:
            VAxis=-VAxis                                                                          
        UAxis=om.MVector.kXaxisVector # this is not a real normal! just an intermiediate vector 
        if abs(VAxis*UAxis)>0.99:
            UAxix=om.MVector.kZaxisVector
        WAxis=UAxis^VAxis
        WAxis.normalize()
        UAxis=VAxis^WAxis
        UAxis.normalize()

        # Find the quaternion that form the coordinate transformation of 
        # joint's local framework: how the new coordinate get back into world coordinate
        quaternion=getQuaternion(UAxis,VAxis,WAxis)
        
        transform_name=self.joint_name+"_cross_section"+"_u_at_"+str(int(self.u_parameter*100))+"_percentage"
        dirPath=cmds.workspace(q=True, rootDirectory=True )
               
        #EXTRACT CROSS SECTION CURVES
        meshFn=om.MFnMesh(self.mesh_dagPath)
        raySource=om.MFloatPoint(ray_center)
        eps=om.MPointArray()
        eps.clear()
        epsLocal=om.MPointArray()
        epsLocal.clear()
            
        for i in range(0,self.division):
            angle=2*math.pi*float(i)/float(self.division)
            ray=UAxis.rotateBy(om.MQuaternion(angle,VAxis))
            rayDirection=om.MFloatVector(ray)
            
            try:
                hitPoint, hitRayParam, hitFace, hitTriangle, hitBary1, hitBary2 = meshFn.closestIntersection(raySource,rayDirection,om.MSpace.kWorld,9999,False,idsSorted=False,tolerance=0.001)    
            except:
                raise
            else:
                eps.append(hitPoint)
                hitPointLocal=om.MVector(hitPoint[0],hitPoint[1],hitPoint[2])
                hitPointLocal-=ray_center
                # This is the quaternion that transform a point from world coordinate into local coordinate 
                # Hence, we need to inverse the quaternion we get above
                hitPointLocal=hitPointLocal.rotateBy(quaternion.inverse())
                epsLocal.append(hitPointLocal)
                
        curveFn=om.MFnNurbsCurve()
        self.cross_section_obj=curveFn.createWithEditPoints(eps,2,om.MFnNurbsCurve.kClosed, False, False, True)
       
        dgFn=om.MFnDependencyNode(self.cross_section_obj)
        dgFn.setName(transform_name)
                
        # add custom attribute to node
        attrFn=om.MFnNumericAttribute()
        uAttr=attrFn.create("uParameter","u",om.MFnNumericData.kFloat,self.u_parameter)
        attrFn.readable=True 
        attrFn.storable=True # fairly consistent, won't change in compute() or get updated by upstream node, etc
        attrFn.writable=True 
        attrFn.keyable=True
        attrFn.hidden=False
        dgFn.addAttribute( uAttr)
                       
        om.MPxCommand.setResult(om.MFnDependencyNode(self.cross_section_obj).name())
                                #,om.MFnDependencyNode(self.cross_section_obj_meta).name()])
        save_path=dirPath+'data/'
        complete_name=os.path.join(save_path,transform_name+'.dat')
        outFile=open(complete_name,'w+')# Here we used "w" letter in our argument, which indicates write and the plus sign that means it will create a file if it does not exist in library
        for i in range(0,self.division):
            x=epsLocal[i].x
            y=epsLocal[i].y
            z=epsLocal[i].z
            outFile.write('{} {} {} \n'.format(x,y,z))
            
        outFile.close()
Esempio n. 25
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. 26
0
def sang(chue_tem_file,
         satsuan=1,
         yaek_poly=False,
         ao_bs=True,
         ao_kraduk=True,
         watsadu=1):
    t_roem = time.time()  # 開始
    print('モデルインポート開始')

    sakun = os.path.splitext(chue_tem_file)[1]  # 拡張子

    try:
        if (sakun == '.pmx'):
            pmx_model = mmdio.pmx.load(chue_tem_file)
        elif (sakun == '.pmd'):
            pmx_model = mmdio.pmd.load2pmx(chue_tem_file)
        elif (sakun == '.x'):
            pmx_model = mmdio.xxx.load2pmx(chue_tem_file)
        else:
            print('pmxとpmdとxファイルしか使用できません')
            raise
    except:
        print('モデルに何か問題があって、ファイルの読み込みは失敗です')
        raise

    chue_nod_model = romaji(pmx_model.name)  # モデルの名前をロマジに変換してモデルのノードの名前にする
    if (not chue_nod_model or set(chue_nod_model) == {'_'}):
        chue_nod_model = os.path.basename(chue_tem_file).split('.')[1]
    lis_chue_nod_kho_nok = []  # 一番外のジョイントのノードの名前を収めるリスト
    chue_nod_skin = None
    chue_nod_bs = None
    # その名前のノードがすでに存在している場合'_'を追加する
    while (mc.objExists(chue_nod_model)):
        chue_nod_model += '_'

    print('ポリゴン作成')
    if (yaek_poly):  # ポリゴンを分割する場合、今まだ何もしなくていい
        lis_chue_nod_poly_mat = []
    else:
        # pmxモデルから頂点の位置とuv一つずつ入れていく
        lis_xyz = []  # 頂点の位置を収めるリスト
        lis_u = []  # 頂点のuvを収めるリスト
        lis_v = []
        lis_norm = []  # 頂点の法線を収めるリスト
        for vtx in pmx_model.vertices:
            try:
                lis_xyz.append(
                    om.MFloatPoint(vtx.co[0] * satsuan, vtx.co[1] * satsuan,
                                   -vtx.co[2] * satsuan))
            except:  # 大きすぎたりとエラーが出る場合もあるので、(0,0,0)にする
                lis_xyz.append(om.MFloatPoint(0, 0, 0))
            lis_u.append(vtx.uv[0])  # 頂点のuvをリストに収める
            lis_v.append(1. - vtx.uv[1])
            if (vtx.normal):  # 頂点の法線のデータがあった場合
                lis_norm.append(
                    om.MFloatVector(vtx.normal[0], vtx.normal[1],
                                    -vtx.normal[2]))

        lis_index_chut = []  # この面に使う頂点を収めるリスト
        lis_n_chut_nai_na = []  # この面に使う頂点の数を収めるリスト
        lis_na_ni_chai_mai = []  # この面が使うかどうかという情報を収めるリスト
        for i_chut_nai_na in pmx_model.faces:
            i_chut_nai_na = list(dict.fromkeys(i_chut_nai_na))  # この面に使う頂点
            n_chut_nai_na = len(i_chut_nai_na)  # この面に使う頂点の数
            if (n_chut_nai_na >= 3):  # 重複しない頂点が3以上ある場合のみ、この面を使う
                lis_index_chut.extend(i_chut_nai_na)
                lis_n_chut_nai_na.append(n_chut_nai_na)
                lis_na_ni_chai_mai.append(True)  # この面を使う
            else:
                lis_na_ni_chai_mai.append(False)  # この面を使わない

        chue_nod_poly = sang_poly(chue_nod_model, lis_xyz, lis_index_chut,
                                  lis_n_chut_nai_na, lis_u, lis_v, lis_norm)

        if (not watsadu):  # 材質を使わないと選択したら全部ただのlambertにする
            mc.select(chue_nod_poly)
            mc.hyperShade(assign='lambert1')

    set_index_tex = set([mat.texture for mat in pmx_model.materials])
    lis_chue_nod_file = []  # テクスチャファイルの名前を収めるリスト
    # テクスチャを作成する
    for i, tex in enumerate(pmx_model.textures):
        path_tem_tex = tex.path
        chue_tex = os.path.basename(path_tem_tex)  # テクスチャの名前
        chue_tex = re.sub(r'\W', '_', chue_tex)
        chue_tex = romaji(chue_tex)  # テクスチャの名前をロマジにする
        chue_nod_file = chue_tex + '_file_' + chue_nod_model
        # 使われているテクスチャだけshadingNodeのノードを作る
        if (i in set_index_tex):
            # 同じ名前が既存である場合、ノードの名前が自動的に変更される
            chue_nod_file = mc.shadingNode('file',
                                           asTexture=True,
                                           name=chue_nod_file)
            mc.setAttr(chue_nod_file + '.ftn', path_tem_tex, typ='string')
            # place2dのノードを作る
            chue_nod_placed2d = mc.shadingNode('place2dTexture',
                                               asUtility=True,
                                               name=chue_tex + '_placed2d_' +
                                               chue_nod_model)
            # place2dノードの値とファイルノードの値を接続する
            for cp in chueam_placed2d:
                mc.connectAttr('%s.%s' % (chue_nod_placed2d, cp[0]),
                               '%s.%s' % (chue_nod_file, cp[1]),
                               force=1)

        lis_chue_nod_file.append(chue_nod_file)

    # 材質を作成する
    nap_na_nai_mat = 0  # すでに材質を付けた面の数
    for i_mat, mat in enumerate(pmx_model.materials):
        if (mat.vertex_count == 0):  # 面一つもないならスキップ
            continue
        n_na_nai_mat = int(mat.vertex_count / 3)  # この材質を付ける面の数
        chue_mat = romaji(mat.name)
        chue_nod_mat = chue_mat + '_mat_' + chue_nod_model

        i_tex = mat.texture  # この材質に付けるテクスチャの番号
        dc = mat.diffuse[:3]  # 拡散色
        ambc = mat.ambient  # 環境色
        spec = mat.specular[:3]  # 反射色
        alpha = mat.diffuse[3]  # 不透明度
        opa = [alpha, alpha, alpha]
        trans = [1 - alpha, 1 - alpha, 1 - alpha]  # 透明度
        sf = mat.specular[3]  # 反射強度

        if (watsadu == 1):
            chue_nod_mat = mc.shadingNode('blinn',
                                          asShader=True,
                                          name=chue_nod_mat)
            mc.setAttr(chue_nod_mat + '.specularColor', *spec, typ='double3')
            mc.setAttr(chue_nod_mat + '.specularRollOff',
                       min(0.75**(math.log(max(sf, 2**-10), 2) + 1), 1))
            mc.setAttr(chue_nod_mat + '.eccentricity', sf * 0.01)
        elif (watsadu == 2):
            chue_nod_mat = mc.shadingNode('phong', asShader=1, n=chue_nod_mat)
            mc.setAttr(chue_nod_mat + '.specularColor', *spec, typ='double3')
            mc.setAttr(chue_nod_mat + '.cosinePower',
                       max((10000. / max(sf, 15)**2 - 3.357) / 0.454, 2))
        elif (watsadu == 3 or not watsadu):
            chue_nod_mat = mc.shadingNode('lambert',
                                          asShader=1,
                                          name=chue_nod_mat)

        if (watsadu in [1, 2, 3]):
            mc.setAttr(chue_nod_mat + '.color', *dc, typ='double3')
            mc.setAttr(chue_nod_mat + '.ambientColor', *ambc, typ='double3')
            mc.setAttr(chue_nod_mat + '.transparency', *trans, typ='double3')
        elif (watsadu == 4):  # arnoldを使う場合
            chue_nod_mat = mc.shadingNode('standardSurface',
                                          asShader=True,
                                          name=chue_nod_mat)
            mc.setAttr(chue_nod_mat + '.baseColor', *dc, typ='double3')
            mc.setAttr(chue_nod_mat + '.specularColor', *spec, typ='double3')
            mc.setAttr(chue_nod_mat + '.opacity', *opa, typ='double3')
            mc.setAttr(chue_nod_mat + '.specular',
                       0.75**(math.log(max(sf, 0.5), 2) + 1))
            mc.setAttr(chue_nod_mat + '.specularRoughness', min(sf * 0.01, 1))
            mc.setAttr(chue_nod_mat + '.base', 1)

        # 日本語の名前も一応収めておく
        mc.addAttr(chue_nod_mat,
                   longName='namae',
                   niceName='名前',
                   dataType='string')
        mc.setAttr(chue_nod_mat + '.namae', mat.name, typ='string')
        if (i_tex >= 0):
            chue_nod_file = lis_chue_nod_file[i_tex]
            if (watsadu != 4):
                mc.connectAttr(chue_nod_file + '.outColor',
                               chue_nod_mat + '.color')
            else:
                mc.connectAttr(chue_nod_file + '.outColor',
                               chue_nod_mat + '.baseColor')

            tex = pmx_model.textures[i_tex]
            if (mc.getAttr(chue_nod_file + '.fileHasAlpha')
                    and tex.path[-3:].lower() in ['png', 'tga', 'dds', 'bmp']):
                # テクスチャノードのアルファを材質ノードに接続する
                if (watsadu in [1, 2, 3]):
                    mc.connectAttr(chue_nod_file + '.outTransparency',
                                   chue_nod_mat + '.transparency')
                elif (watsadu == 4):
                    mc.connectAttr(chue_nod_file + '.outAlpha',
                                   chue_nod_mat + '.opacityR')
                    mc.connectAttr(chue_nod_file + '.outAlpha',
                                   chue_nod_mat + '.opacityG')
                    mc.connectAttr(chue_nod_file + '.outAlpha',
                                   chue_nod_mat + '.opacityB')

        chue_nod_sg = mc.sets(renderable=1,
                              noSurfaceShader=1,
                              empty=1,
                              name=chue_nod_mat + 'SG')
        mc.connectAttr(chue_nod_mat + '.outColor',
                       chue_nod_sg + '.surfaceShader',
                       force=True)

        if (yaek_poly):
            lis_index_chut_mat = []
            lis_n_chut_nai_na_nai_mat = []
            dic_chut = {}
            k = 0
            for i_chut_nai_na in pmx_model.faces[
                    nap_na_nai_mat:nap_na_nai_mat + n_na_nai_mat]:
                i_chut_nai_na = list(dict.fromkeys(i_chut_nai_na))
                n_chut_nai_na = len(i_chut_nai_na)
                if (n_chut_nai_na >= 3):
                    for j in range(n_chut_nai_na):
                        if (i_chut_nai_na[j] not in dic_chut):
                            dic_chut[i_chut_nai_na[j]] = k  # 元の番号と新しい番号を繋ぐ辞書
                            k += 1
                        lis_index_chut_mat.append(dic_chut[i_chut_nai_na[j]])
                    lis_n_chut_nai_na_nai_mat.append(n_chut_nai_na)

            lis_xyz_mat = []
            lis_u_mat = []
            lis_v_mat = []
            lis_norm_mat = []
            for ic in dic_chut:
                k = dic_chut[ic]
                vtx = pmx_model.vertices[ic]
                try:
                    lis_xyz_mat.append(
                        om.MFloatPoint(vtx.co[0] * satsuan,
                                       vtx.co[1] * satsuan,
                                       -vtx.co[2] * satsuan))
                except:
                    lis_xyz_mat.append(om.MFloatPoint(0, 0, 0))
                lis_u_mat.append(vtx.uv[0])
                lis_v_mat.append(1. - vtx.uv[1])
                lis_norm_mat.append(
                    om.MFloatVector(vtx.normal[0], vtx.normal[1],
                                    -vtx.normal[2]))

            # この材質のポリゴンを作成する
            chue_nod_poly_mat = sang_poly(chue_nod_model + '_%d' % (i_mat + 1),
                                          lis_xyz_mat, lis_index_chut_mat,
                                          lis_n_chut_nai_na_nai_mat, lis_u_mat,
                                          lis_v_mat, lis_norm_mat)
            n_na_chai_mat = len(lis_n_chut_nai_na_nai_mat)  # 実際に使う面の数
            mc.sets(chue_nod_poly_mat + '.f[%s:%s]' % (0, n_na_chai_mat - 1),
                    forceElement=chue_nod_sg)
            lis_chue_nod_poly_mat.append(chue_nod_poly_mat)
        else:
            nap_na_chai0 = sum(lis_na_ni_chai_mai[:nap_na_nai_mat])
            nap_na_chai1 = sum(lis_na_ni_chai_mai[:nap_na_nai_mat +
                                                  n_na_nai_mat])
            # 指定の面に材質を貼る
            mc.sets(chue_nod_poly + '.f[%s:%s]' %
                    (nap_na_chai0, nap_na_chai1 - 1),
                    forceElement=chue_nod_sg)

        nap_na_nai_mat += n_na_nai_mat  # 面の数を数え続ける

    if (yaek_poly):
        chue_nod_poly = mc.group(lis_chue_nod_poly_mat, name=chue_nod_model)

    if (ao_bs and not yaek_poly):
        print('ブレンドシェープ作成')
        # 各パネル(眉、目、口、他)
        lis_chue_nod_poly_bs = [[], [], [],
                                []]  # ブレンドシェープを作るためのポリゴンのノードのリストを収める
        lis_chue_bs_doem = [[], [], [], []]  # 元の名前(日本の名前)を収めるリスト
        for i, mo in enumerate(pmx_model.morphs):
            # 頂点モーフをブレンドシェープに変換する。他のモーフは変換できないので無視する
            if (mo.type_index() == 1):
                # ブレンドシェープの名前はロマジに変換しなければならない
                chue_bs = romaji(mo.name)
                # ブレンドシェープを作るために、元のポリゴンをコピーする
                chue_nod_poly_bs = mc.duplicate(chue_nod_poly, name=chue_bs)[0]

                selelis = om.MSelectionList()
                selelis.add(chue_nod_poly_bs)
                dagpath = selelis.getDagPath(0)
                fn_mesh = om.MFnMesh(dagpath)
                arr_chut = fn_mesh.getPoints()  # 頂点の位置が入っている配列

                for off in mo.offsets:
                    vi = off.index  # 動く頂点の番号
                    d = off.offset  # 元の位置から動く距離
                    p = arr_chut[vi]  # 元の頂点のいち
                    arr_chut[vi] = [
                        p[0] + d[0] * satsuan, p[1] + d[1] * satsuan,
                        p[2] - d[2] * satsuan
                    ]  # 頂点が動いた後の位置を配列に入れる

                fn_mesh.setPoints(arr_chut)
                lis_chue_nod_poly_bs[mo.category - 1].append(chue_nod_poly_bs)
                lis_chue_bs_doem[mo.category - 1].append(mo.name)

        # 一つのリストにする。順番はパネルによる
        lis_chue_nod_poly_bs = list(itertools.chain(*lis_chue_nod_poly_bs))
        mc.select(lis_chue_nod_poly_bs, chue_nod_poly)
        # ブレンドシェープのノードを作成する
        chue_nod_bs = mc.blendShape(name='bs_' + chue_nod_poly)[0]
        mc.delete(lis_chue_nod_poly_bs)  # すでにブレンドシェープを作るために使ったポリゴンは用済みだから消す

    if (ao_kraduk and not yaek_poly):
        print('ジョイント作成')
        lis_chue_nod_kho = []  # ジョイントの名前を収めるリスト
        for b in pmx_model.bones:
            mc.select(deselect=1)
            chue_kho = romaji(b.name)
            loc = b.location  # ジョイントの位置
            # ジョイントの半径
            if ('yubi' in chue_kho):  # 指は小さめ
                r_kho = satsuan / 4
            elif (chue_kho == 'sentaa'):  # サンターは大きめ
                r_kho = satsuan
            else:  # その他
                r_kho = satsuan / 2
            # ジョイントのノードを作成する
            chue_nod_kho = mc.joint(position=[
                loc[0] * satsuan, loc[1] * satsuan, -loc[2] * satsuan
            ],
                                    radius=r_kho,
                                    name=chue_nod_poly + '_' + chue_kho)
            mc.addAttr(chue_nod_kho,
                       longName='namae',
                       niceName='名前',
                       dataType='string')  # 日本語の名前も一応ここに収めておく
            mc.setAttr(chue_nod_kho + '.namae', b.name, typ='string')

            if (b.isIK or not b.visible):  # 表示しないジョイント
                mc.setAttr(chue_nod_kho + '.drawStyle', 2)
            else:
                mc.setAttr(chue_nod_kho + '.drawStyle', 0)
            # ローカル軸が指定されている場合
            if (b.localCoordinate or b.axis):
                if (b.axis):  # x軸だけが指定されている場合
                    kaen_x = b.axis
                    kaen_z = cross([0.0, 1.0, 0.0], kaen_x)
                else:  # x軸もz軸も指定されている場合
                    kaen_x = b.localCoordinate.x_axis
                    kaen_z = b.localCoordinate.z_axis
                kaen_y = cross(kaen_z, kaen_x)
                # ジョイントの方向を表すオイラー角に変換するための行列
                matrix_mun = om.MMatrix([
                    kaen_x[0], kaen_x[1], -kaen_x[2], 0., kaen_y[0], kaen_y[1],
                    -kaen_y[2], 0., kaen_z[0], kaen_z[1], -kaen_z[2], 0., 0.,
                    0., 0., 1.
                ])
                mum_euler = om.MTransformationMatrix(matrix_mun).rotation()
                # できたオイラー角の単位がラジアンなので角度に変換する
                ox = math.degrees(mum_euler.x)
                oy = math.degrees(mum_euler.y)
                oz = math.degrees(mum_euler.z)
                mc.setAttr(chue_nod_kho + '.jointOrient', ox, oy,
                           oz)  # ジョイントの方向

            lis_chue_nod_kho.append(chue_nod_kho)

        for i, b in enumerate(pmx_model.bones):
            chue_nod_kho = lis_chue_nod_kho[i]
            if (b.parent >= 0):
                # ジョイントを結び合う
                chue_nod_parent = lis_chue_nod_kho[b.parent]
                mc.connectJoint(chue_nod_kho, chue_nod_parent, parentMode=1)
            else:
                lis_chue_nod_kho_nok.append(chue_nod_kho)

            # 回転角の不具合がある場合の解決
            if (round(mc.getAttr(chue_nod_kho + '.rx')) % 360 == 0):
                mc.setAttr(chue_nod_kho + '.rx', 0)
            if (round(mc.getAttr(chue_nod_kho + '.ry')) % 360 == 0):
                mc.setAttr(chue_nod_kho + '.ry', 0)
            if (round(mc.getAttr(chue_nod_kho + '.rz')) % 360 == 0):
                mc.setAttr(chue_nod_kho + '.rz', 0)
            if (round(mc.getAttr(chue_nod_kho + '.rx')) % 360 == 180
                    and round(mc.getAttr(chue_nod_kho + '.ry')) % 360 == 180
                    and round(mc.getAttr(chue_nod_kho + '.rz')) % 360 == 180):
                mc.setAttr(chue_nod_kho + '.r', 0, 0, 0)

            if (b.hasAdditionalRotate):
                # 回転付与のあるジョイントの場合
                chue_nod_effect = lis_chue_nod_kho[
                    b.additionalTransform[0]]  # 影響を与えるノード
                jo = mc.getAttr(chue_nod_effect +
                                '.jointOrient')[0]  # このジョイントの方向を取得
                mc.setAttr(chue_nod_kho + '.jointOrient', *jo)  # 同じジョイントの方向にする

                # 回転付与をエクスプレッションにする
                ef = b.additionalTransform[1]  # 付与率
                s = '%s.rotateX = %s.rotateX * %s;\n' % (chue_nod_kho,
                                                         chue_nod_effect, ef)
                s += '%s.rotateY = %s.rotateY * %s;\n' % (chue_nod_kho,
                                                          chue_nod_effect, ef)
                s += '%s.rotateZ = %s.rotateZ * %s;\n' % (chue_nod_kho,
                                                          chue_nod_effect, ef)
                mc.expression(string=s,
                              name='expression_%s_%s' %
                              (chue_nod_kho, chue_nod_effect))

            if (b.hasAdditionalLocation):
                # 移動付与をエクスプレッションにする
                chue_nod_effect = lis_chue_nod_kho[
                    b.additionalTransform[0]]  # 影響を与えるノード
                ef = b.additionalTransform[1]  # 付与率
                s = '%s.translateX = %s.translateX * %s;\n' % (
                    chue_nod_kho, chue_nod_effect, ef)
                s += '%s.translateY = %s.translateY * %s;\n' % (
                    chue_nod_kho, chue_nod_effect, ef)
                s += '%s.translateZ = %s.translateZ * %s;\n' % (
                    chue_nod_kho, chue_nod_effect, ef)
                mc.expression(string=s,
                              name='expression_%s_%s' %
                              (chue_nod_kho, chue_nod_effect))

        selelis = om.MSelectionList()
        selelis.add(chue_nod_poly)
        dagpath_mesh = selelis.getDagPath(0)

        chue_nod_skin = 'skin_' + chue_nod_poly
        chue_nod_skin = mc.skinCluster(lis_chue_nod_kho,
                                       chue_nod_poly,
                                       maximumInfluences=4,
                                       toSelectedBones=True,
                                       name=chue_nod_skin)[0]  # スキンのノードを作成する
        selelis = om.MSelectionList()
        selelis.add(chue_nod_skin)
        obj_skin = selelis.getDependNode(0)
        fn_skin = oma.MFnSkinCluster(obj_skin)

        n_kho = len(pmx_model.bones)
        lis_namnak = []  # 重みの値を収めるリスト
        for vtx in pmx_model.vertices:
            namnak = [0.] * n_kho  # この頂点に対する各ジョイントの影響の重み
            if (vtx.weight.type == mmdio.pmx.BoneWeight.BDEF1):
                # 2つだけのジョイントの影響を受ける場合
                namnak[vtx.weight.bones[0]] = 1.
            elif (vtx.weight.type == mmdio.pmx.BoneWeight.BDEF2):
                # 2つのジョイントの影響を受ける場合
                namnak[vtx.weight.bones[0]] += vtx.weight.weights[0]
                namnak[vtx.weight.bones[1]] += 1. - vtx.weight.weights[0]
            elif (vtx.weight.type == mmdio.pmx.BoneWeight.SDEF):
                # SDEFの場合もBDEF2と同様に2つのジョイント扱い
                namnak[vtx.weight.bones[0]] += vtx.weight.weights.weight
                namnak[vtx.weight.bones[1]] += 1. - vtx.weight.weights.weight
            elif (vtx.weight.type == mmdio.pmx.BoneWeight.BDEF4):
                # 4つのジョイントの影響を受ける場合
                namnak[vtx.weight.bones[0]] += vtx.weight.weights[0]
                namnak[vtx.weight.bones[1]] += vtx.weight.weights[1]
                namnak[vtx.weight.bones[2]] += vtx.weight.weights[2]
                namnak[vtx.weight.bones[3]] += 1. - vtx.weight.weights[
                    0] - vtx.weight.weights[1] - vtx.weight.weights[2]
            lis_namnak.extend(namnak)

        n_chut = len(pmx_model.vertices)  # 頂点の数
        arr_index_chut = om.MIntArray(range(n_chut))  # 頂点の番号の配列
        arr_namnak = om.MDoubleArray(lis_namnak)  # 重みの値の配列
        arr_index_influ = om.MIntArray(range(n_kho))  # ジョイントの番号の配列
        fn_compo = om.MFnSingleIndexedComponent()
        compo = fn_compo.create(om.MFn.kMeshVertComponent)
        fn_compo.addElements(arr_index_chut)
        # ポリゴンに対するそれぞれのジョウントの影響の重みの値を設置する
        fn_skin.setWeights(dagpath_mesh, compo, arr_index_influ, arr_namnak, 1)

        for chue_nod_kho in lis_chue_nod_kho:
            if (chue_nod_kho not in lis_chue_nod_kho_nok):
                mc.rename(chue_nod_kho,
                          chue_nod_kho.replace(chue_nod_poly + '_', ''))

    # 日本語の名前も一応収めておく
    mc.addAttr(chue_nod_poly,
               longName='namae',
               niceName='名前',
               dataType='string')
    mc.setAttr(chue_nod_poly + '.namae', pmx_model.name, typ='string')

    mc.select(chue_nod_poly)
    if (ao_kraduk):
        mc.select(lis_chue_nod_kho_nok)

    try:
        mc.setAttr('hardwareRenderingGlobals.transparencyAlgorithm', 3)
        mc.setAttr('defaultArnoldRenderOptions.autotx', 0)
        mc.setAttr('defaultArnoldRenderOptions.use_existing_tiled_textures', 0)
    except:
        0

    print('モデルインポート完了。%.2f秒かかりました' % (time.time() - t_roem))
    return chue_nod_poly, lis_chue_nod_kho_nok, chue_nod_skin, chue_nod_bs
Esempio n. 27
0
    def compute(self, pPlug, pDataBlock):
        '''
        Node computation method.
          - pDataBlock contains the data on which we will base our computations.
          - pPlug is a connection point related to one of our node attributes (either an input or an output).
        '''
        if (pPlug == depthShader.outColorAttribute):

            # Get the data handles corresponding to your attributes among the values in the data block.
            surfacePointDataHandle = pDataBlock.inputValue(
                depthShader.surfacePointAttribute)
            nearDistanceDataHandle = pDataBlock.inputValue(
                depthShader.nearDistanceAttribute)
            farDistanceDataHandle = pDataBlock.inputValue(
                depthShader.farDistanceAttribute)
            nearColorDataHandle = pDataBlock.inputValue(
                depthShader.nearColorAttribute)
            farColorDataHandle = pDataBlock.inputValue(
                depthShader.farColorAttribute)
            gammaDataHandle = pDataBlock.inputValue(depthShader.gammaAttribute)

            # Obtain the (x,y,z) location of the currently rendered point in camera coordinates.
            surfacePoint = surfacePointDataHandle.asFloatVector()

            # Since the camera is looking along its negative Z axis (the Y axis is
            # the up vector), we must take the absolute value of the Z coordinate
            # to obtain the point's depth.
            depth = abs(surfacePoint.z)

            # Get the actual near and far threshold values.
            nearValue = nearDistanceDataHandle.asFloat()
            farValue = farDistanceDataHandle.asFloat()

            # Find the proportion of depth between the near and far values.
            if ((farValue - nearValue) == 0):
                # Avoid a division by zero if the near and far values somehow have the same value.
                depthProportion = 0
            else:
                depthProportion = (depth - nearValue) / (farValue - nearValue)

            # Clamp the depthProportion value in the interval [0.0, 1.0]
            depthProportion = max(0, min(depthProportion, 1.0))

            # Modify the depth proportion using the gamma roll-off bias.
            gammaValue = gammaDataHandle.asFloat()
            depthProportion = math.pow(depthProportion, gammaValue)

            # Linearly interpolate the output color based on the depth proportion.
            outColor = OpenMaya.MFloatVector(0, 0, 0)
            nearColor = nearColorDataHandle.asFloatVector()
            farColor = farColorDataHandle.asFloatVector()

            outColor.x = nearColor.x + (
                (farColor.x - nearColor.x) * depthProportion)
            outColor.y = nearColor.y + (
                (farColor.y - nearColor.y) * depthProportion)
            outColor.z = nearColor.z + (
                (farColor.z - nearColor.z) * depthProportion)

            # Write to the output data.
            outColorDataHandle = pDataBlock.outputValue(
                depthShader.outColorAttribute)
            outColorDataHandle.setMFloatVector(outColor)
            outColorDataHandle.setClean()
        else:
            return OpenMaya.kUnknownParameter
Esempio n. 28
0
    def compute(self, pq, dt):
        for boid in range(pq.nb_items):
            kr = 0.0
            kf = 0.0
            a_avoid = om.MFloatVector(0.0, 0.0, 0.0)
            a_velMat = om.MFloatVector(0.0, 0.0, 0.0)
            a_center = om.MFloatVector(0.0, 0.0, 0.0)
            _amax = self.amax

            # If the boid is the leader
            if boid == self.leadBoid_index:
                boid_dir = (self.leadBoid_goal - pq.pos[boid]).normal()
                pq.accel[boid] = boid_dir * self.amax
                continue

            for neighbor in range(pq.nb_items):
                if neighbor == boid:
                    continue
                xa = pq.pos[boid]  #type: om.MFloatVector
                xb = pq.pos[neighbor]  #type: om.MFloatVector
                va = pq.vel[boid]  #type: om.MFloatVector
                vb = pq.vel[neighbor]  #type: om.MFloatVector

                # Influence Range
                r = (xa - xb).length()
                if r < self.range:
                    kr = 1
                elif r > self.range and r < self.range_ramp:
                    kr = (self.range_ramp - r) / (self.range_ramp - self.range)
                elif r > self.range_ramp:
                    kr = 0

                # Influence FOV
                t = (xb - xa).normalize() * va.normal()
                if t > self.cosfovshell:
                    kf = 1
                elif t > self.cosfov and t < self.cosfovshell:
                    kf = (self.cosfov - t) / (self.cosfov - self.cosfovshell)
                elif t < self.cosfov:
                    kf = 0

                # Avoidance
                a_avoid += (self.A * (xa - xb).normalize() *
                            (1 / (xa - xb).length()) * kr * kf
                            )  #type: om.MFloatVector
                # Velocity Matching
                a_velMat += (self.V * (vb - va) * kr * kf)
                # Centering
                a_center += (self.C * (xb - xa) * kr * kf)

            # Acceleration Prioritization
            a_len = a_avoid.length()
            if a_len > self.amax:
                a_avoid = _amax * a_avoid.normal()
                a_velMat = a_center = om.MFloatVector(0.0, 0.0, 0.0)
            else:
                _amax = _amax - a_len
                a_len = a_velMat.length()
                if a_len > _amax:
                    a_velMat = _amax * a_velMat.normal()
                    a_center = om.MFloatVector(0.0, 0.0, 0.0)
                else:
                    _amax = _amax - a_len
                    a_len = a_center.length()
                    if a_len > _amax:
                        a_center = _amax * a_center.normal()
            aTotal = a_avoid + a_velMat + a_center

            # If the boid is the lead boid
            pq.accel[boid] = aTotal
Esempio n. 29
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. 30
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