コード例 #1
0
def setWeigths(skinNode, geo, inf, weigth):
    #获得一个组件列表
    cmp_list = [universal.intoComponents(i) for i in universal.translateToName(geo)]
    #检查组件列表的数量
    if len(cmp_list)<1:
        raise EOFError('geo没有任何对象')
    #建立一个组件选择列表
    sel_list = om.MSelectionList()
    [sel_list.add(i) for i in cmp_list]
    if int(sel_list.length())>1:
        raise EOFError('%s 不在一个mesh或者其他对象上'%geo)
        return 1
    path,comp = sel_list.getComponent(0)
    sel_list.add(skinNode)
    skinNode = sel_list.getDependNode(1)


    fn_skin = oma.MFnSkinCluster(skinNode)

    m_inf = om.MIntArray(inf)
    m_weigth = om.MDoubleArray(weigth)
    #撤销的权重
    unWeights = fn_skin.getWeights(path,comp,m_inf)

    doIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,m_weigth)
    undoIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,unWeights)
    return cmcore.addCommand(doIt, undoIt)
コード例 #2
0
    def doIt(self, *args):

        # NOTE(fuzes): Here we only gather the data for the command and then call the reDoIt() method to do the rest of the job
        argDB = om2.MArgDatabase(self.syntax(), args[0])

        if argDB.isFlagSet("-pn"):
            self._plugName = argDB.flagArgumentString("-pn", 0)
            if not self._plugName in _PER_VERTEX_ATTRIBUTE_NAMES:
                m_cmds.error("Invalid Plug Name")
                return
        else:
            m_cmds.error("plugName flag must be set")

        selList = argDB.getObjectList()
        mob = selList.getDependNode(0)
        self._nObjectMobHandle = om2.MObjectHandle(mob)

        if argDB.isFlagSet("-vw"):
            self._current_weights = om2.MDoubleArray()
            for i in xrange(argDB.numberOfFlagUses("-vw")):
                argList = argDB.getFlagArgumentList("-vw", i)
                self._current_weights.append(argList.asDouble(0))
        else:
            m_cmds.error("vertexWeight flag must be set")

        self.redoIt()
コード例 #3
0
    def redoIt(self):
        # get the skin cluster MObject by going up the history

        fnSkinCluster = omAnim.MFnSkinCluster(self.skinClusterMObject)

        oldVertexWeight, numInfluences = fnSkinCluster.getWeights(
            self.dagPath, self.component)
        neighborVertexWeights, numInfluences = fnSkinCluster.getWeights(
            self.dagPath, self.neighborComponents)

        influenceIndices = om.MIntArray()
        newWeights = om.MDoubleArray()

        for i in xrange(numInfluences):
            # set the vertex weight to the average of its neighbor parts
            influenceIndices.append(i)
            newWeights.append(0.0)
            for j in xrange(i, len(neighborVertexWeights), numInfluences):
                # add to a rolling average. This will be normalized by default.
                # NOTE bmorgan: This formula comes from tf_smoothSkinWeight
                newWeights[i] += (
                    ((neighborVertexWeights[j] / self.numVertexNeighbors) *
                     self.strength) +
                    ((oldVertexWeight[i] / self.numVertexNeighbors) *
                     (1 - self.strength)))

        fnSkinCluster.setWeights(self.dagPath, self.component,
                                 influenceIndices, newWeights)

        self.undoQueue.append((self.skinClusterMObject, oldVertexWeight,
                               self.dagPath, influenceIndices, self.component))
    def redoIt(self):
        fnSkinCluster = omAnim.MFnSkinCluster(self.skinClusterMObject)

        # get the weights for our single vertex plus its neighbors
        oldVertexWeight, numInfluences = fnSkinCluster.getWeights(self.shapeDag, self.component)
        neighborVertexWeights, numInfluences = fnSkinCluster.getWeights(self.shapeDag, self.neighborComponents)
        neighborVertexWeightLength = self.numVertexNeighbors * numInfluences

        influenceIndices = om.MIntArray()
        newWeights = om.MDoubleArray()

        # set the vertex weight to the average of its neighbor parts
        for i in xrange(numInfluences):
            # taking advantage of this loop to create our influence indices array
            influenceIndices.append(i)
            # weights start at 0 so that we can add weight values to it
            newWeights.append(0.0)
            for j in xrange(i, neighborVertexWeightLength, numInfluences):
                # add to a rolling average. This will be normalized by default.
                # NOTE bmorgan: This formula comes from tf_smoothSkinWeight
                newWeights[i] += (((neighborVertexWeights[j] / self.numVertexNeighbors) * self.strength) +
                                  ((oldVertexWeight[i] / self.numVertexNeighbors) * (1 - self.strength)))

        # set the skin cluster weight for just that single component
        fnSkinCluster.setWeights(self.shapeDag, self.component, influenceIndices, newWeights)

        # add the previous weight value to our undo queue
        self.undoQueue.append((self.skinClusterMObject, oldVertexWeight, self.shapeDag, influenceIndices, self.component))
コード例 #5
0
def makeCurvFromPoints(cvs_array, transform_fn=None):
    """
	Generate a spline from an array of points.
	:param cvs_array:  MPointArray to generate curve from.
	:param transform_fn:  Optional argument for parenting curve under existing transform.
	:return:  TransformFn, NurbsCurveFn
	"""
    knot_vector = om2.MDoubleArray()

    # calculate knot vector
    degree = 2
    nspans = len(cvs_array) - degree
    nknots = nspans + 2 * degree - 1

    for i in range(degree - 1):
        knot_vector.append(0.0)
    for j in range(nknots - (2 * degree) + 2):
        knot_vector.append(j)
    for k in range(degree - 1):
        knot_vector.append(j)

    # create curve
    if transform_fn is None:
        transform_fn = om2.MFnTransform()
        transform_fn.create()
        # transform_fn.setName('%s_input_curv' % name)

    curvFn = om2.MFnNurbsCurve()
    curvFn.create(cvs_array, knot_vector, degree, om2.MFnNurbsCurve.kOpen,
                  False, True, transform_fn.object())

    return transform_fn, curvFn
コード例 #6
0
ファイル: animFilters.py プロジェクト: saphilli/AnimFiltersV2
def add_keys(anim_curve, key_dict):
    # type: (unicode, dict) -> None
    """
    Add keyframes to animation curve

    :param anim_curve: animation curve name
    :param key_dict: dictionary of keyframes in {frame_number (float): value (float)} format
    :return: None
    """

    unit = om.MTime.uiUnit()
    nodeNattr = cmds.listConnections(anim_curve, d=True, s=False, p=True)[0]
    selList = om.MSelectionList()
    selList.add(nodeNattr)
    mplug = selList.getPlug(0)
    dArrTimes = om.MTimeArray()
    dArrVals = om.MDoubleArray()

    if 'rotate' in nodeNattr:
        for i in key_dict.keys():
            dArrTimes.append(om.MTime(float(i), unit))
            dArrVals.append(om.MAngle.uiToInternal(key_dict[i]))
    else:
        for i in key_dict.keys():
            dArrTimes.append(om.MTime(float(i), unit))
            dArrVals.append(key_dict[i])

    crvFnc = oma.MFnAnimCurve(mplug)
    crvFnc.addKeys(dArrTimes, dArrVals, crvFnc.kTangentAuto, crvFnc.kTangentAuto)
コード例 #7
0
    def redoIt(self, *args):

        nMob = getNObjectMobFromMob(self._nObjectMobHandle.object())
        if nMob.isNull():
            m_cmds.error("Selection has no relationship with nObjects")
            return

        mfn_dep_nCloth = om2.MFnDependencyNode(nMob)
        plug = mfn_dep_nCloth.findPlug(self._plugName, False)

        dataHandle = plug.asMDataHandle()
        data = dataHandle.data()
        isDataNull = data.isNull()

        # NOTE(Fuzes): If the Data is Null we set it ourselves, else we work on the reference
        if isDataNull:
            newData = om2.MFnDoubleArrayData()
            mobData = newData.create(self._current_weights)
            dataHandle.setMObject(mobData)
            plug.setMDataHandle(dataHandle)
            self._needsUndo = True
            return
        else:
            doubleArrayData = om2.MFnDoubleArrayData(data)
            self._prev_weights = om2.MDoubleArray()
            for i, value in enumerate(self._current_weights):
                self._prev_weights.append(doubleArrayData[i])
                doubleArrayData[i] = value
            self._needsUndo = True
            return
コード例 #8
0
 def setBlendWeights(self,weigth):
     #执行的权重
     m_weigth = om.MDoubleArray(weigth)
     #撤销的权重
     unWeights = self.fn_skin.getBlendWeights(self.path,self.comp)
     doIt = functools.partial(self.fn_skin.setBlendWeights,self.path,self.comp,m_weigth)
     undoIt = functools.partial(self.fn_skin.setBlendWeights,self.path,self.comp,unWeights)
     return cmcore.addCommand(doIt, undoIt)
コード例 #9
0
def set_skin_cluster_weights(mesh, skin_cluster, weights):
    """Set all weights on skin cluster via MFnSkinCluster.

    Weights should be in same form as returned by
    get_skin_cluster_weights.

    TODO options for selective influences.
    TODO options for selective components.

    """
    sl = OpenMaya.MSelectionList()

    # get mesh dag path
    sl.add(mesh)
    mesh_dag = sl.getDagPath(0)

    # get skin
    sl.add(skin_cluster)
    m_skin = sl.getDependNode(1)

    # restructure weights to match form expected by MFnSkinCluster
    n_weights = numpy.array(weights)
    flat_weights = n_weights.transpose().flatten().tolist()
    weights = OpenMaya.MDoubleArray(flat_weights)

    if True:
        # construct component object for all verts
        # TODO perform on specific components?!?
        mesh_fn = OpenMaya.MFnMesh(mesh_dag)
        point_count = mesh_fn.numVertices

        component = OpenMaya.MFnSingleIndexedComponent()
        component.create(OpenMaya.MFn.kMeshVertComponent)
        component.addElements([i for i in range(point_count)])

        components = component.object()

    else:
        # or simply pass in an empty MObject to set all weights
        # note sometimes this doesn't work?!
        components = OpenMaya.MObject()

    # set weights
    m_skin = OpenMayaAnim.MFnSkinCluster(m_skin)

    influences = [
        m_skin.indexForInfluenceObject(i) for i in m_skin.influenceObjects()
    ]

    # influences must be passed in as a MIntArray
    # python list will throw an unhelpful error
    # Error: TypeError: file ...py line 116: an integer is required #

    influences = OpenMaya.MIntArray(influences)

    m_skin.setWeights(mesh_dag, components, influences, weights)

    return True
コード例 #10
0
    def vtxLoad_api(self):
        selList = om.MGlobal.getActiveSelectionList()
        if selList.isEmpty():
            om.MGlobal.displayError('Select Nothing')
            return
        MDagPath = selList.getDagPath(0)  # 存储所选物体的路径
        MObject = selList.getDependNode(0)  # 存储所选物体的组件的列表

        _selType = MDagPath.apiType()
        _selShapeType = MDagPath.extendToShape().apiType()
        if _selType != 110:
            om.MGlobal.displayError('Please Select Object')
            return
        if _selShapeType != 296:
            self.vtxLoad_Oapi()
            return

        skCluster = mel.eval('findRelatedSkinCluster("%s")' % MDagPath.partialPathName())
        if not skCluster:
            return
        selList.add(skCluster)
        skinObj = selList.getDependNode(1)
        skinNode = omAni.MFnSkinCluster(skinObj)
        infs = skinNode.influenceObjects()
        infNameList = [infs[i].partialPathName() for i in range(len(infs))]  # 骨骼列表

        filePath = cmds.fileDialog2(ff='WeightFile (*.vtxWeight *.sdd)', ds=2, fm=1)
        if not filePath:
            return
        allLine = self.readWeightData_Load(filePath[0])
        if allLine == 'toMel':
            om.MGlobal.displayWarning('Some Error. Please ReSelect')
            self.vtxLoad_Mel()
            return

        jntLock = []
        for j in infNameList:
            jntLock.append(cmds.getAttr(j + '.liw'))
            cmds.setAttr(j + '.liw', 0)
        vertIter = om.MItMeshVertex(MObject)
        _Num = 0
        while not vertIter.isDone():
            if vertIter.index() != int(allLine[_Num][0]):
                vertIter.next()
                continue
            jntindex = om.MIntArray()
            weights = om.MDoubleArray()
            jntindexapp = jntindex.append
            weightsapp = weights.append
            for i in range(len(allLine[_Num][1])):
                jntindexapp(infNameList.index(allLine[_Num][1][i]))
                weightsapp(allLine[_Num][2][i])
            skinNode.setWeights(MDagPath, vertIter.currentItem(), jntindex, weights, False)  # False规格化开关默认为True
            _Num += 1
            vertIter.next()
        for j, l in zip(infNameList, jntLock):
            cmds.setAttr(j + '.liw', l)
        DisplayYes().showMessage('Process Finish!')
コード例 #11
0
    def setWeigths(self,inf,weigth):
        m_inf = om.MIntArray(inf)
        #执行的权重
        m_weigth = om.MDoubleArray(weigth)
        #撤销的权重
        unWeights = self.fn_skin.getWeights(self.path,self.comp,m_inf)

        doIt = functools.partial(self.fn_skin.setWeights,self.path,self.comp,m_inf,m_weigth)
        undoIt = functools.partial(self.fn_skin.setWeights,self.path,self.comp,m_inf,unWeights)
        return cmcore.addCommand(doIt, undoIt)
コード例 #12
0
    def __init__(self):
        super(AverageVertexWeightsCommand, self).__init__()

        self._index_arg = ''
        self._weight_arg = None
        self._skin_cluster_arg = ''

        self._skin_fn = None
        self._components = None
        self._influence_indices = None
        self._dag_path = OpenMaya.MDagPath()
        self._old_weights = OpenMaya.MDoubleArray()
コード例 #13
0
def clearWeights(attribute):
    """Clear the deformer weights of the given attribute by assigning
    an empty array. This is much faster than iterating through all
    weights indices individually and removing them.

    :param attribute: The full path of the weights attribute which
                      should get cleared.
    :type attribute: str
    """
    sel = om2.MSelectionList()
    sel.add(attribute)
    plug = sel.getPlug(0)
    emptyArray = om2.MDoubleArray()
    dataFn = om2.MFnDoubleArrayData()
    obj = dataFn.create(emptyArray)
    plug.setMObject(obj)
コード例 #14
0
def maya_api_addkeys(plugName, times, values):
    sel = OpenMaya.MSelectionList()
    sel.add(plugName)
    plug = sel.getPlug(0)

    animFn = OpenMayaAnim.MFnAnimCurve()
    animFn.create(plug, OpenMayaAnim.MFnAnimCurve.kAnimCurveTL)

    timeArray = OpenMaya.MTimeArray()
    valueArray = OpenMaya.MDoubleArray()

    for i in range(len(times)):
        timeArray.append(OpenMaya.MTime(times[i], OpenMaya.MTime.kSeconds))
        valueArray.append(values[i])

    animFn.addKeys(timeArray, valueArray)
コード例 #15
0
ファイル: main.py プロジェクト: ziyeshanwai/ssds
def bindToSkin(meshPaths, skinIndex, skinWeight, skinJnts, numMaxInfluences):
    asl = om.MSelectionList()
    asl.clear()
    jntNames = [sj.name for sj in skinJnts]
    for sj in skinJnts:
        m = om.MMatrix(sj.bindPose.tolist())
        m = om.MTransformationMatrix(m)
        om.MFnTransform(sj.path).setTransformation(m)
        asl.add(sj.path)
    offset = 0
    for meshPath in meshPaths:
        mesh = om.MFnMesh(meshPath)
        meshName = om.MFnDagNode(mesh.parent(0)).name()
        skinNode = findSkinCluster(meshPath)
        if skinNode:
            cmds.skinCluster(meshName, edit=True, unbind=True)
        sl = om.MSelectionList(asl)
        sl.add(meshPath)
        om.MGlobal.setActiveSelectionList(sl)
        meshName = om.MFnDagNode(mesh.parent(0)).name()
        skinName = cmds.skinCluster(maximumInfluences=numMaxInfluences,
                                    name=meshName + 'Cluster',
                                    toSelectedBones=True)[0]
        skinObj = om.MGlobal.getSelectionListByName(skinName).getDependNode(0)
        skin = oma.MFnSkinCluster(skinObj)
        vertexIndices = om.MIntArray(mesh.numVertices, 0)
        for i in xrange(mesh.numVertices):
            vertexIndices[i] = i
        singleIndexedComp = om.MFnSingleIndexedComponent()
        vertexComp = singleIndexedComp.create(om.MFn.kMeshVertComponent)
        singleIndexedComp.addElements(vertexIndices)
        infDags = skin.influenceObjects()
        numInfDags = len(infDags)
        infIndices = om.MIntArray(numInfDags, 0)
        for i in xrange(numInfDags):
            infIndices[i] = i
        weights = om.MDoubleArray(mesh.numVertices * numInfDags, 0)
        for v in xrange(mesh.numVertices):
            for j, w in zip(skinIndex[offset + v], skinWeight[offset + v]):
                if j >= 0:
                    weights[v * numInfDags + j] = w
        skin.setWeights(meshPath, vertexComp, infIndices, weights)
        offset += mesh.numVertices
        skin.findPlug('deformUserNormals', True).setBool(False)
コード例 #16
0
ファイル: ctrlFunctions.py プロジェクト: Jennykinns/Jenks
def applyShapeData(ctrlName,
                   crvData,
                   transOffset=(0, 0, 0),
                   rotOffset=(0, 0, 0),
                   scaleOffset=(1, 1, 1)):
    """ Applies the supplied curve data to the specified control.
    [Args]:
    ctrlName (string) - The name of the control to change
    crvData (string) - The point data to apply
    transOffset (int, int, int) - The translation offset to apply
                                  to the new crv data
    rotOffset (int, int, int) - The rotation offset to apply
                                to the new crv data
    scaleOffset (int, int, int) - The scale offset to apply
                                  to the new crv data
    """
    curveShapes = utils.getShapeNodes(ctrlName)
    ctrlMObj = api.getMObj(ctrlName)
    if curveShapes:
        for each in curveShapes:
            cmds.delete(each)
    for crvShape in crvData.keys():
        nurbsCrv = om.MFnNurbsCurve()
        cvArray = om.MPointArray()
        for i, x in enumerate(crvData[crvShape]['CVs']):
            cvArray.append((x['x'], x['y'], x['z']))
            cvArray[i] = (api.transformMPoint(cvArray[i],
                                              rot=rotOffset,
                                              trans=transOffset,
                                              scale=scaleOffset))
        knotArray = om.MDoubleArray()
        for x in crvData[crvShape]['knots']:
            knotArray.append(x)
        degree = crvData[crvShape]['degree']
        form = crvData[crvShape]['form']
        nurbsCrv.create(cvArray, knotArray, degree, form, 0, 1, ctrlMObj)
        if 'color' in crvData[crvShape].keys():
            utils.setColor(nurbsCrv.name(), color=crvData[crvShape]['color'])

    shapes = utils.getShapeNodes(ctrlName)
    for i, each in enumerate(shapes):
        cmds.rename(each, '{}Shape{}'.format(ctrlName, i + 1))
コード例 #17
0
    def doIt(self, *args):

        # NOTE(fuzes): Here we only gather the data for the command
        argDB = om2.MArgDatabase(self.syntax(), args[0])

        if argDB.isFlagSet("-pn"):
            plugName = argDB.flagArgumentString("-pn", 0)
            if not plugName in _PER_VERTEX_ATTRIBUTE_NAMES:
                m_cmds.error("Invalid Plug Name")
                return
        else:
            m_cmds.error("plugName flag must be set")

        selList = argDB.getObjectList()
        mob = selList.getDependNode(0)
        nMob = getNObjectMobFromMob(mob)
        if nMob.isNull():
            m_cmds.error("Selection has no relationship with nObjects")
            return

        mfn_dep_nCloth = om2.MFnDependencyNode(nMob)
        plug = mfn_dep_nCloth.findPlug(plugName, False)

        dataHandle = plug.asMDataHandle()
        data = dataHandle.data()
        isDataNull = data.isNull()

        result = om2.MDoubleArray()
        if isDataNull:
            self.clearResult()
            self.setResult(result)
        else:
            doubleArrayData = om2.MFnDoubleArrayData(data)
            result = doubleArrayData.array()
            self.clearResult()
            self.setResult(result)
コード例 #18
0
    def redoIt(self):
        self._dag_path, self._components = self._get_mesh()

        surrounding_weights = OpenMaya.MDoubleArray()
        surrounding_vertex_array = OpenMaya.MIntArray()
        influences_count = 0
        influence = None

        vertex_iterator = OpenMaya.MItMeshVertex(self._dag_path,
                                                 self._components)
        surrounding_vertex_array = vertex_iterator.getConnectedVertices()
        surrounding_components = OpenMaya.MFnSingleIndexedComponent().create(
            OpenMaya.MFn.kMeshVertComponent)
        OpenMaya.MFnSingleIndexedComponent(surrounding_components).addElements(
            surrounding_vertex_array)

        self._old_weights, influence = self._skin_fn.getWeights(
            self._dag_path, self._components)
        surrounding_weights, influence = self._skin_fn.getWeights(
            self._dag_path, surrounding_components)

        print(self._old_weights)
        print(surrounding_weights)
        print(influence)
コード例 #19
0
ファイル: ctrlFunctions.py プロジェクト: Jennykinns/Jenks
def getShapeData(ctrlName, color=False):
    """ Gets the shape data of the control.
    [Args]:
    ctrlName (string) - The name of the control
    color (bool) - Toggles if the function will store the colour
                   information
    [Returns]:
    crvData (string) - The point data of the control shape
    """
    curveShapes = utils.getShapeNodes(ctrlName)
    crvData = {}
    for i, each in enumerate(curveShapes):
        crvData[i] = {}
        crvData[i]['CVs'] = []
        crvData[i]['knots'] = []

        nurbsCrv = api.getNurbsCurve(each)
        cvArray = om.MPointArray()
        knotArray = om.MDoubleArray()
        cvArray = nurbsCrv.cvPositions(om.MSpace.kObject)
        knotArray = nurbsCrv.knots()

        for cvNum in range(len(cvArray)):
            cv = {
                'x': cvArray[cvNum].x,
                'y': cvArray[cvNum].y,
                'z': cvArray[cvNum].z
            }
            crvData[i]['CVs'].append(cv)
        crvData[i]['knots'].extend(knotArray)
        crvData[i]['degree'] = nurbsCrv.degree
        crvData[i]['form'] = nurbsCrv.form
        if color:
            crvData[i]['color'] = cmds.getAttr('{}.overrideColor'.format(each))

    return crvData
コード例 #20
0
def __simplify_weights(mesh, target, skin, start=None, end=None, steps=1):
    """
    Sets each vertex to follow the single joint that produces the least difference
    in position over the given frame range


    :param mesh:
    :param target:
    :param skin:
    :param start:
    :param end:
    :param steps:
    :return:
    """
    # Verify we have the right number of vertices
    numVerts = mesh.numVertices
    if target.numVertices != numVerts:
        raise RuntimeError("Target Mesh has a different vertex count")

    # Figure out the start and end range
    if start is None:
        start = mc.playbackOptions(minTime=True, query=True)
    if end is None:
        end = mc.playbackOptions(maxTime=True, query=True)
    start = int(math.floor(start))
    end = int(math.ceil(end))
    currentTime = mc.currentTime(query=True)

    same_mesh = mesh.fullPathName() == target.fullPathName()
    space = om.MSpace.kObject

    # Lets get the weights
    vertices = range(mesh.numVertices)
    influence_indexes, vertex_cmpt, weights = get_weights(mesh, skin, vertices)

    deltas = [0.0 for x in weights]
    stride = len(influence_indexes)

    # We'll calculate the pattern of the list before hand so we aren't calculating
    # it on every frame
    preweights = []
    for i in range(stride):
        preweights.append([float(x == i) for x in range(stride)])

    # Now go through the frame range
    for frame in range(start, end + 1, steps):
        logger.info('Processing frame %s', frame)
        mc.currentTime(frame)

        # If we have the same mesh, restore the default weights on each frame before we continue
        if same_mesh:
            skin.setWeights(mesh.dagPath(), vertex_cmpt, influence_indexes,
                            weights)
        target_points = mesh.getPoints(space)

        # Set each vertex weight to full then measure the distance and add to the deltas
        for i in range(stride):
            skin.setWeights(mesh.dagPath(), vertex_cmpt, influence_indexes,
                            om.MDoubleArray(preweights[i] * numVerts))

            points = mesh.getPoints()
            for vtx, point in enumerate(points):
                # Then calculate the distance between the vertexes.
                tpoint = target_points[vtx]
                distance = math.sqrt(((point.x - tpoint.x)**2) +
                                     ((point.y - tpoint.y)**2) +
                                     ((point.z - tpoint.z)**2))

                deltas[(vtx * stride) + i] += distance

    for vtx in vertices:
        vtx_deltas = deltas[vtx * stride:(vtx * stride) + stride]
        idx = min(enumerate(vtx_deltas), key=lambda x: x[1])[0]
        weights[vtx * stride:(vtx * stride) +
                stride] = preweights[idx] * numVerts

    skin.setWeights(mesh.dagPath(), vertex_cmpt, influence_indexes, weights)
    mc.currentTime(currentTime)
コード例 #21
0
    def doIt(self, args):
        # メッシュの取得
        dagPath = om.MGlobal.getActiveSelectionList().getDagPath(0)
        meshFn = om.MFnMesh(dagPath)
        if meshFn is None:
            raise

        # 変換時間範囲の取得
        startTime = oma.MAnimControl.animationStartTime()
        endTime = oma.MAnimControl.animationEndTime()
        numFrames = int((endTime - startTime).asUnits(om.MTime.uiUnit())) + 1
        oma.MAnimControl.setCurrentTime(startTime)

        # 先頭フレームの形状(world座標系)をバインド姿勢として登録
        points = meshFn.getPoints(om.MSpace.kWorld)
        numVertices = len(points)
        bindVertices = []
        for p in points:
            bindVertices += [p.x, p.y, p.z]

        # 変換対象シェイプアニメーションの取得
        time = om.MTime(startTime)
        animVertices = []
        while time <= endTime:
            oma.MAnimControl.setCurrentTime(time)
            points = meshFn.getPoints(om.MSpace.kWorld)
            for p in points:
                animVertices += [p.x, p.y, p.z]
            time += 1
        # ひとまず先頭フレームに移動
        oma.MAnimControl.setCurrentTime(startTime)
        # SSDR本体 : 戻り値は平方根平均二乗誤差(RMSE)
        rmse = ssdr.build(self.numMinBones, self.numMaxInfluences,
                          self.numMaxIterations, bindVertices, animVertices,
                          numVertices, numFrames)
        # 推定されたボーン数
        numBones = ssdr.getNumBones()
        om.MGlobal.displayInfo('RMSE = ' + str(rmse) + ', #Bones = ' +
                               str(numBones))
        # C++モジュール内部に格納されているスキンウェイトとボーンインデクスの情報を取得
        #  [頂点1のウェイト1, 頂点1のウェイト2, ..., 頂点2のウェイト1, ... , 頂点Nのウェイト1, ... , ] のような並び
        #  ボーンインデクスも同じ並び
        skinningWeight = ssdr.getSkinningWeight()
        skinningIndex = ssdr.getSkinningIndex()

        # 複製されるメッシュの名前を適当に指定
        newSkinName = 'SsdrMesh'
        # メッシュの複製
        cmds.duplicate(meshFn.name(), returnRootsOnly=True, name=newSkinName)

        # 複製されたシェイプに紐付けるボーン群を生成
        #
        # ボーンのリスト
        bones = []
        for b in range(numBones):
            cmds.select(d=True)
            # ボーン名は適当な接頭辞+番号
            bone = cmds.joint(name='SsdrBone{0}'.format(b + 1))
            # ニュートラル状態(先頭フレーム)におけるボーンの姿勢をC++モジュールから取得
            #  平行移動
            t = ssdr.getBoneTranslation(b, 0)
            #  回転クォータニオン
            q = ssdr.getBoneRotation(b, 0)
            u = om.MQuaternion(q[0], q[1], q[2], q[3])
            e = u.asEulerRotation()
            cmds.move(t[0], t[1], t[2], bone, relative=False)
            cmds.rotate(e.x, e.y, e.z, bone, relative=False)
            # リストに追加
            bones.append(bone)
        # 複製メッシュとボーン群をグループ化
        newGroup = cmds.group(newSkinName, bones, name='SsdrResult')

        # スキンクラスタの生成
        ssdrRig = cmds.skinCluster(bones,
                                   newSkinName,
                                   maximumInfluences=self.numMaxInfluences,
                                   name='skinClusterSsdr')[0]
        # スキンクラスタとスキンメッシュの取得
        skinNode = om.MGlobal.getSelectionListByName(ssdrRig).getDependNode(0)
        skinFn = oma.MFnSkinCluster(skinNode)
        meshPath = om.MGlobal.getSelectionListByName(newSkinName).getDagPath(0)

        # 全頂点を対象にスキニング情報を更新
        indices = om.MIntArray(numVertices, 0)
        for i in xrange(len(indices)):
            indices[i] = i
        singleIndexedComp = om.MFnSingleIndexedComponent()
        vertexComp = singleIndexedComp.create(om.MFn.kMeshVertComponent)
        singleIndexedComp.addElements(indices)
        # インフルエンスオブジェクトの情報
        infDags = skinFn.influenceObjects()
        numInfluences = len(infDags)
        infIndices = om.MIntArray(numInfluences, 0)
        for i in xrange(numInfluences):
            infIndices[i] = i
        # ウェイトの設定
        weights = om.MDoubleArray(numVertices * numInfluences, 0)
        for v in xrange(numVertices):
            for i in xrange(self.numMaxInfluences):
                weights[v * numInfluences +
                        skinningIndex[v * self.numMaxInfluences +
                                      i]] = skinningWeight[
                                          v * self.numMaxInfluences + i]
        skinFn.setWeights(meshPath, vertexComp, infIndices, weights)

        # ボーンモーションを設定
        startTime = cmds.playbackOptions(min=True, query=True)
        for f in range(numFrames):
            frame = startTime + f
            for b in range(numBones):
                t = ssdr.getBoneTranslation(b, f)
                q = ssdr.getBoneRotation(b, f)
                u = om.MQuaternion(q[0], q[1], q[2], q[3])
                e = u.asEulerRotation()
                cmds.setKeyframe(bones[b], t=frame, at='tx', v=t[0])
                cmds.setKeyframe(bones[b], t=frame, at='ty', v=t[1])
                cmds.setKeyframe(bones[b], t=frame, at='tz', v=t[2])
                cmds.setKeyframe(bones[b],
                                 t=frame,
                                 at='rx',
                                 v=math.degrees(e.x))
                cmds.setKeyframe(bones[b],
                                 t=frame,
                                 at='ry',
                                 v=math.degrees(e.y))
                cmds.setKeyframe(bones[b],
                                 t=frame,
                                 at='rz',
                                 v=math.degrees(e.z))
コード例 #22
0
ファイル: ImportAnimCurve.py プロジェクト: dayelov/MayaPython
                        MFnAnimCurve = oma.MFnAnimCurve(connectedNode)
                        newAnimCurve = 0

                if newAnimCurve:
                    MFnAnimCurve = oma.MFnAnimCurve()

                    MFnAnimCurve.create(attributeMPlug, animCurveType)

                # set value
                MFnAnimCurve.setPreInfinityType(preInfinity)
                MFnAnimCurve.setPostInfinityType(postInfinity)

                MFnAnimCurve.setIsWeighted(weightedTangents)

                MTimeArray = om.MTimeArray()
                MDoubleValueList = om.MDoubleArray()

                for index in range(len(timeList)):
                    MTimeArray.append(om.MTime(timeList[index]), om.MTime.uiUnit())
                    MDoubleValueList.append(valueList[index])

                MFnAnimCurve.addKeys(MTimeArray, MDoubleValueList, 0, 0, 1)

                for index in range(len(timeList)):
                    MFnAnimCurve.setInTangentType(index, inTangentTypeList[index])
                    MFnAnimCurve.setOutTangentType(index, outTangentTypeList[index])

                    inTangentAngle = om.MAngle(inTangentAngleList[index])
                    outTangentAngle = om.MAngle(outTangentAngleList[index])

                    MFnAnimCurve.setAngle(index, inTangentAngle, 1)
コード例 #23
0
def set_nurbsCurve_data(node, curves_data, world_space=False):
    """Set the nurbsCurve shapes' data on `node`.

    Parameters
    ----------
    node : maya.api.OpenMaya.MObject
        A DAG node in the scene
    curves_data : list
        List of nurbsCurve data
    world_space : bool
        If True, assign the nurbsCurve data in world space. Otherwise, assign the data
        local to the node.
    """

    dagMod = OpenMaya.MDagModifier()

    number_of_curves = len(curves_data)

    curves = [
        obj for obj in iter_shapes(node) if obj.hasFn(OpenMaya.MFn.kNurbsCurve)
    ]

    excess = len(curves) - number_of_curves

    if excess > 0:
        for i in range(excess):
            obj = curves.pop(-1)
            dagMod.deleteNode(obj)
    elif excess < 0:
        for i in range(-excess):
            obj = dagMod.createNode('nurbsCurve', node)
            curves.append(obj)

    dagMod.doIt()

    for data, curve in zip(curves_data, curves):
        curve_fn = OpenMaya.MFnNurbsCurve()

        curveData_fn = OpenMaya.MFnNurbsCurveData()
        curveData_obj = curveData_fn.create()

        if world_space:
            wm = get_world_matrix(curve)
        else:
            wm = OpenMaya.MMatrix(data['worldMatrix'])

        wim = wm.inverse()

        cvs = [OpenMaya.MPoint(p) * wim for p in data['cvs']]
        knots = OpenMaya.MDoubleArray(data['knots'])

        curve_fn.create(cvs, knots, data['degree'], data['form'], False, True,
                        curveData_obj)

        create_plug = OpenMaya.MFnDagNode(curve).findPlug('create', True)

        if is_locked_or_connected(create_plug):
            raise ValueError()

        create_plug.setMObject(curveData_obj)

    return dagMod
コード例 #24
0
selection = mc.ls(sl=True)
mMatrixArray = ompy.MMatrixArray()
for elem in selection:
    matrixNumTmp = mc.xform(elem, q=True, matrix=True, ws=True)
    mMatrix = ompy.MMatrix(matrixNumTmp)
    mMatrixArray.append(mMatrix)
#GET POINT FROM MATRIX
positions = ompy.MPointArray()
for i in range(0, len(mMatrixArray)):
    mTrs = ompy.MTransformationMatrix(mMatrixArray[i])
    mVector = mTrs.translation(ompy.MSpace.kWorld)
    mPoint = ompy.MPoint(mVector.x, mVector.y, mVector.z)
    positions.append(mPoint)
#GET Knot
nbrKnot = len(positions) + degree - 1
knotsValues = ompy.MDoubleArray()
for i in range(0, 3):
    knotsValues.append(0.0)
for i in range(1, nbrKnot - 5):
    knotsValues.append(i / (nbrKnot - 5.0))
for i in range(nbrKnot - 3, nbrKnot):
    knotsValues.append(1.0)

for i in range(0, len(knotsValues)):
    print(knotsValues[i])

#FILL ATTR
curve = ompy.MFnNurbsCurve()
cvs = positions
knots = knotsValues
form = curve.kOpen
コード例 #25
0
ファイル: pmxpaimaya.py プロジェクト: phyblas/mmdpaimaya
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
コード例 #26
0
ファイル: testSKin——2.py プロジェクト: 2921251087/CPMel-1
#检查组件列表的数量
if len(cmp_list)<1:
    raise EOFError('geo没有任何对象')
#建立一个组件选择列表
sel_list = om.MSelectionList()
[sel_list.add(i) for i in cmp_list]
if int(sel_list.length())>1:
    raise EOFError('%s 不在一个mesh或者其他对象上'%geo)
    return 1
path,comp = sel_list.getComponent(0)
sel_list.add(skinNode)
skinNode = sel_list.getDependNode(1)

fn_skin = oma.MFnSkinCluster(skinNode)
m_inf = om.MIntArray(inf)
m_weigth = om.MDoubleArray(weigth)
unWeights = fn_skin.getWeights(path,comp,m_inf)

doIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,m_weigth)
undoIt = functools.partial(fn_skin.setWeights,path,comp,m_inf,unWeights)
cmcore.addCommand(doIt, undoIt)

fl_array = fn_skin.getBlendWeights(path,comp)
fn_skin.setBlendWeights(path,comp,fl_array)



class SetWeights:
    '''
    操作蒙皮权重的类
    setWeigths(self,inf,weigth)#设置蒙皮权重