animTrans

# coding=UTF-8
import maya.cmds as mc
from decimal import *


class BindConData:
    def __init__(self):
        self.conData = {}
        self.CurveCon = []
        self.tempCurveCon = []
        self.unKeyCon = []
        self.TransCons = {}
        self.constList = {}
        self.searchKey = ['ALLGrp', 'Face_Grp']
        self.countConst = True  # 设置是否要检查约束
        self.iskey = False  # 设置是否是被key过的角色
        self.isdebug = 'no debug'
        self.newDelConst = []
        self.newConst = []
        self.oldConst = []
        self.polarBear = ''

    def objfilter(self, selObj):
        grpList = self.getRfObjs(selObj)
        for i in grpList:
            self.tempCurveCon = mc.listRelatives(i, ad=True, fullPath=True, typ='transform')
            for i in self.tempCurveCon:
                tempS = mc.listRelatives(i, fullPath=True, shapes=True)
                if tempS:
                    if mc.nodeType(tempS[0]) == 'nurbsCurve' and ('follicle' not in i):
                        self.CurveCon.append(i)

        del self.tempCurveCon[:]
        self.tempCurveCon.extend(self.CurveCon)
        if self.isdebug == 'objfilter' or self.isdebug == 'all':
            print(len(self.tempCurveCon))
        del self.CurveCon[:]
        self.iskeied()
        self.getData(self.CurveCon)

    def iskeied(self):
        '''
        检查每个curveCon链接的constraint 存入self.constList字典 key为环名 值为约束的列表
        tempC为有key了帧的环才存入 self.iskey为true self.curveCon将等于tempC
        self.tempCurveCon依然为全控制环的组
        '''
        tempC = []
        tempUnC = []
        for i in self.tempCurveCon:
            if self.countConst == True:
                tempCL = mc.listConnections(i, type='constraint')
                if tempCL:
                    tempCL2 = self.listRebuild(tempCL)
                else:
                    tempCL2 = None
                self.constList[i] = tempCL2

            tempOL = mc.keyframe(i, query=True)
            if tempOL:
                tempC.append(i)
            else:
                tempUnC.append(i)
        if self.iskey == True:
            self.CurveCon = tempC
            self.unKeyCon = tempUnC
        else:
            self.CurveCon = self.tempCurveCon
        print(len(self.constList))
        if self.isdebug == 'iskeied' or self.isdebug == 'all':
            print('tempC:{0}'.format(tempC))
            print('\n')
            print('iskeied函数结束')

    def getData(self, CurveConList):
        '''
        获得self.CurveCon里所有控制环的属性值
        存入self.conData字典的对应环名字下存储方式为:环名<-属性名<-key了帧的frame<-[[动画曲线参数unicode],[动画曲线参数数字]]
       '''

        if CurveConList:
            for i in CurveConList:
                tempAttrDict = {}
                tempAttrL = mc.keyframe(i, query=True, name=True)
                if tempAttrL:
                    for j in tempAttrL:
                        shortAttr = self.attrNameRebuild(j, i)
                        tempFrameList = mc.keyframe(i, attribute=shortAttr, query=True)
                        tempFrameDict = {}
                        for k in tempFrameList:
                            try:
                                tempvalueL = []
                                tempstrL = []
                                tempflL = []
                                tempValue = mc.keyframe(j, query=True, vc=True, t=(k, k))
                                tempValue1 = Decimal(str(tempValue[0])).quantize(Decimal('0.00'))
                                inAng = mc.keyTangent(j, query=True, ia=True, t=(k, k))
                                inTT = mc.keyTangent(j, query=True, itt=True, t=(k, k))
                                outAng = mc.keyTangent(j, query=True, oa=True, t=(k, k))
                                outTT = mc.keyTangent(j, query=True, ott=True, t=(k, k))
                                inW = mc.keyTangent(j, query=True, iw=True, t=(k, k))
                                outW = mc.keyTangent(j, query=True, ow=True, t=(k, k))
                                tempflL.append(float(tempValue1))
                                tempflL.append(inAng[0])
                                tempstrL.append(inTT[0])
                                tempflL.append(outAng[0])
                                tempstrL.append(outTT[0])
                                tempflL.append(inW[0])
                                tempflL.append(outW[0])
                                tempvalueL.append(tempflL)
                                tempvalueL.append(tempstrL)
                                tempFrameDict[k] = tempvalueL
                            except:
                                print("控制环{0}属性{1}出错".format(i, j))

                        tempAttrDict[shortAttr] = tempFrameDict
                else:
                    shortAttrL = mc.listAttr(i, k=True, v=True, u=True)
                    if shortAttrL:
                        for j in shortAttrL:
                            tempAttrDict[j] = 0

                self.conData[i] = tempAttrDict

        if self.isdebug == 'getData' or self.isdebug == 'all':
            print('getData阶段完成')
            print(len(self.conData))

    def getRfObjs(self, selObj):
        '''
        找到selObj的引用节点并获得其下所有包含dag
        '''
        grpList = []
        objList = []
        rf = mc.referenceQuery(selObj, referenceNode=True, topReference=True)
        if rf:
            objList = mc.referenceQuery(rf, n=True, dp=True)
        else:
            print('{0}的引用节点未读取到请检查'.format(selObj))
        for i in objList:
            if mc.nodeType(i) == 'transform':
                if i.endswith(self.searchKey[0]) or i.endswith(self.searchKey[1]):
                    tempshape = mc.listRelatives(i, shapes=True, fullPath=True)
                    if not tempshape:
                        grpList.append(i)
        if grpList:
            return grpList
        else:
            print('引用节点{0}包含的顶层group获取失败'.format(rf))

    def listRebuild(self, oriList):
        '''
        oriList内部去重
        '''
        tempList = []
        tempList.append(oriList[0])
        for i in oriList:
            if (i in tempList):
                pass
            else:
                tempList.append(i)
        return tempList

    def attrNameRebuild(self, oriAttr, CurConName):
        '''
        控制器属性名去头尾 重构
        '''
        tempAttrL = mc.listAttr(CurConName, v=True, u=True, k=True)
        for i in tempAttrL:
            if oriAttr.endswith(i) or oriAttr[:-1].endswith(i):
                newattr = i

                return newattr

    def nameCut(self, fullName, selInx):
        ind = fullName.rfind(':')
        indx = fullName.rfind('.')
        if ind == -1:
            ind = 0
        if indx == -1:
            indx = 0
        if selInx == 0:
            ind += 1
            return fullName[ind:]
        elif selInx == 1:
            return fullName[:ind]
        elif selInx == 2:
            return fullName[indx:]

    def transData(self, BCData):
        setKeyInfo = {}
        for conNam_l in self.conData:
            conNam_s = self.nameCut(conNam_l, 0)
            for conNam_l2 in BCData.conData:
                conNam_s2 = self.nameCut(conNam_l2, 0)
                if conNam_s2 == conNam_s:
                    setKeyInfo[conNam_l2] = conNam_l
        for conCurve in setKeyInfo.keys():
            for attr in self.conData[setKeyInfo[conCurve]].keys():
                for frame in self.conData[setKeyInfo[conCurve]][attr].keys():
                    value = self.conData[setKeyInfo[conCurve]][attr][frame][0][0]
                    inAng = self.conData[setKeyInfo[conCurve]][attr][frame][0][1]
                    inTT = self.conData[setKeyInfo[conCurve]][attr][frame][1][0]
                    outAng = self.conData[setKeyInfo[conCurve]][attr][frame][0][2]
                    outTT = self.conData[setKeyInfo[conCurve]][attr][frame][1][1]
                    inW = self.conData[setKeyInfo[conCurve]][attr][frame][0][3]
                    outW = self.conData[setKeyInfo[conCurve]][attr][frame][0][4]
                    # print('conCurve:{0},attribute:{1},time:{2},value:{3}'.format(conCurve,attr,frame,value))

                    mc.setKeyframe(conCurve, t=(frame, frame), at=attr, v=value)
                    mc.keyTangent(conCurve, edit=True, t=(frame, frame), at=attr, ia=inAng, oa=outAng, iw=inW, ow=outW,
                                  itt=inTT, ott=outTT)

        for i in range(len(self.tempCurveCon)):
            if self.tempCurveCon[i] in self.unKeyCon:
                try:
                    self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 2)
                except:
                    print('check{0}'.format(self.tempCurveCon[i]))

        if self.isdebug == 'transData' or self.isdebug == 'all':
            print('data 传递完成')

    def showData(self, ind):
        if ind == 0:
            for i in self.CurveCon:
                print(i)
        elif ind == 1:
            for key in self.conData.keys():
                print(key)
                print('---------')
                print(self.conData[key])
                print('\n')
        elif ind == 2:
            for key in self.constList.keys():
                print(key)
                print('---------')
                print(self.constList[key])
                print('\n')
        elif ind == 3:
            for key in self.TransCons.keys():
                print(key)
                print('---------')
                print(self.TransCons[key])
                print('\n')

    def transState(self, TarCurCon, SouCurCon):
        print('开始transState阶段')
        try:
            pos = mc.xform(SouCurCon, ws=True, a=True, q=True, t=True)
            rot = mc.xform(SouCurCon, ws=True, a=True, q=True, ro=True)
            # sca = mc.xform(SouCurCon, ws=True,a=True,q=True, s=True)
            mc.xform(TarCurCon, ws=True, a=True, t=pos)
            mc.xform(TarCurCon, ws=True, a=True, ro=rot)
            # mc.xform(TarCurCon, ws=True,a=True, s=sca)
        except:
            if self.isdebug == 'transState' or self.isdebug == 'all':
                print('{0}xform失败 建议检查'.format(TarCurCon))

    def transAttrVal(self, TarCurCon, SouCurCon, ind):
        if ind == 0:
            AttrList = [u'translateX', u'translateY', u'translateZ', u'rotateX', u'rotateY', u'rotateZ', u'scaleX',
                        u'scaleY', u'scaleZ', u'visibility', u'FKIKBlend', u'Rotx', u'Roty', u'Rotz', u'Spread',
                        u'spread', u'cup', u'indexCurl', u'middleCurl', u'ringCurl', u'pinkyCurl', u'thumbCurl']
            for attr in AttrList:
                try:
                    tempAttrVal = mc.getAttr(SouCurCon + '.' + attr)
                    mc.setAttr(TarCurCon + '.' + attr, tempAttrVal)
                except:
                    if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
                        print('{0} 的{1}属性未传递  一般是被冻结 可以检查'.format(TarCurCon, attr))
        elif ind == 1:
            tempAttrList = mc.listAttr(SouCurCon, u=True, k=True, ud=True)
            if tempAttrList:
                for at in tempAttrList:
                    tempVal = mc.getAttr(SouCurCon + '.' + at)
                    tempVal1 = mc.getAttr(TarCurCon + '.' + at)
                    if tempVal1 != tempVal:
                        try:
                            mc.setAttr(TarCurCon + '.' + at, tempVal)
                        except:
                            print('{0}控制器的属性{1}未能设置成功'.format(TarCurCon, at))
            else:
                if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
                    print('{0}或{1}控制器无可传递自定义属性值'.format(SouCurCon, TarCurCon))

        elif ind == 2:
            tempAttrList = mc.listAttr(SouCurCon, u=True, k=True)
            if tempAttrList:
                for at in tempAttrList:
                    tempVal = mc.getAttr(SouCurCon + '.' + at)
                    tempVal1 = mc.getAttr(TarCurCon + '.' + at)
                    if tempVal1 != tempVal:
                        try:
                            mc.setAttr(TarCurCon + '.' + at, tempVal)
                        except:
                            print('{0}控制器的属性{1}未能设置成功'.format(TarCurCon, at))
            else:
                if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
                    print('{0}或{1}控制器无可传递自定义属性值'.format(SouCurCon, TarCurCon))

    def preTrans(self, BCData):
        if self.countConst == True:
            tempTransCons = self.constContrast(BCData)
            if tempTransCons:

                self.TransCons = self.listRebuild(tempTransCons)
                self.polarBear = mc.spaceLocator()
                for i in self.TransCons:
                    tempNewCon = self.constraintRec(i, BCData, self.polarBear)
                    self.newDelConst.append(tempNewCon)
                self.delNew()

                if self.oldConst:
                    self.constFrameTrans()
                # for i in self.tempCurveCon:
                #     if
                #     self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 1)
                #     self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 0)

    def constContrast(self, BCData):
        '''
        tempConDict key:约束数量有差别的控制环  value:不相同的约束list
        '''
        tempConDict = []

        if self.constList:
            for ind in range(len(self.tempCurveCon)):
                i = self.tempCurveCon[ind]
                j = BCData.tempCurveCon[ind]
                if self.constList[i] and BCData.constList[j] == None:
                    tempConList = []
                    for k in self.constList[i]:
                        TarObj = mc.listConnections(k + '.constraintParentInverseMatrix', d=True)
                        k1 = TarObj[0] + '|' + k
                        tempConList.append(k1)

                    tempConDict.extend(tempConList)

                if self.constList[i] and BCData.constList[j]:
                    if len(self.constList[i]) > len(BCData.constList[j]):
                        tempConList1 = []
                        shortConL = []
                        for m in self.constList[i]:
                            for n in BCData.constList[j]:
                                shortConL.append(self.nameCut(n, 0))
                            if self.nameCut(m, 0) not in shortConL:
                                TarObj = mc.listConnections(m + '.constraintParentInverseMatrix', d=True)
                                m1 = TarObj[0] + '|' + m
                                tempConList1.append(m1)
                            del shortConL[:]

                        tempConDict.extend(tempConList1)

        if self.isdebug == 'constContrast' or self.isdebug == 'all':
            print(tempConDict)
        print(tempConDict)
        return tempConDict

    def constraintRec(self, constNam, BCData, locNam):
        tempAttr = ''
        newobj = []
        souIn = False
        tarIn = False
        souConstObj = ''
        tarConstObj = ''
        bcdSouConObj = ''
        bcdTarConObj = ''
        if mc.nodeType(constNam) == 'parentConstraint':
            tempAttr = '.constraintTranslateX'
        elif mc.nodeType(constNam) == 'scaleConstraint':
            tempAttr = '.constraintScaleX'
        tempSouConnList = mc.listConnections(constNam + '.target[0].targetParentMatrix', s=True)
        tempTarConnList = mc.listConnections(constNam + tempAttr, d=True)
        for i in range(len(self.tempCurveCon)):
            if self.tempCurveCon[i].endswith(tempSouConnList[0]):
                souIn = True
                souConstObj = self.tempCurveCon[i]
                bcdSouConObj = BCData.tempCurveCon[i]
            if self.tempCurveCon[i].endswith(tempTarConnList[0]):
                tarIn = True
                tarConstObj = self.tempCurveCon[i]
                bcdTarConObj = BCData.tempCurveCon[i]

        if souIn and tarIn:
            print('1_1')
            self.transState(bcdSouConObj, souConstObj)
            newConst = mc.parentConstraint(locNam, bcdSouConObj, mo=True, w=1000)
            self.transState(bcdTarConObj, tarConstObj)
            newConst1 = mc.parentConstraint(locNam, bcdTarConObj, mo=True, w=1000)
            self.oldConst.append(constNam)
            self.reConnectAttr(constNam, bcdSouConObj, bcdTarConObj, 2)
            newobj.append(newConst)
            print('success')
        if souIn and not tarIn:
            print('1_0')
            self.transState(bcdSouConObj, souConstObj)
            newConst = mc.parentConstraint(locNam, bcdSouConObj, mo=True, w=1000)
            self.reConnectAttr(constNam, tempSouConnList[0], bcdSouConObj, 0)
            newobj.append(newConst)
            print('success')
        elif not souIn and tarIn:
            print('0_1')
            self.transState(bcdTarConObj, tarConstObj)
            newConst = mc.parentConstraint(locNam, bcdTarConObj, mo=True, w=1000)
            self.reConnectAttr(constNam, tempTarConnList[0], bcdTarConObj, 1)
            print('success')

        return newobj

    def reConnectAttr(self, constNam, oldObj, newObj, ind):  # oldObj is conCurve
        AttrList = []
        pAttrList1 = ['.target[0].targetParentMatrix', '.target[0].targetRotate', '.target[0].targetRotateOrder',
                      '.target[0].targetRotatePivot', '.target[0].targetRotateTranslate', '.target[0].targetScale',
                      '.target[0].targetTranslate']
        pAttrlist2 = ['.constraintTranslateX', '.constraintTranslateY', '.constraintTranslateZ', '.constraintRotateX',
                      '.constraintRotateY', '.constraintRotateZ', '.constraintParentInverseMatrix',
                      '.constraintRotateOrder', '.constraintRotatePivot', '.constraintRotateTranslate']
        sAttrlist1 = ['.target[0].targetParentMatrix', '.target[0].targetScale']
        sAttrlist2 = ['.constraintScaleX', '.constraintScaleY', '.constraintScaleZ', '.constraintParentInverseMatrix']
        if mc.nodeType(constNam) == 'parentConstraint':
            if ind == 0:
                AttrList = pAttrList1
            elif ind == 1:
                AttrList = pAttrlist2
            elif ind == 2:
                AttrList.append('p')
        elif mc.nodeType(constNam) == 'scaleConstraint':
            if ind == 0:
                AttrList = sAttrlist1
            elif ind == 1:
                AttrList = sAttrlist2
            elif ind == 2:
                AttrList.append('s')
        if len(AttrList) != 1:
            for i in AttrList:
                tempAttr = mc.listConnections(constNam + i, p=True)
                try:
                    mc.disconnectAttr(oldObj + self.nameCut(tempAttr[0], 2), constNam + i)
                    mc.connectAttr(newObj + self.nameCut(tempAttr[0], 2), constNam + i, f=True)
                    print('connect {0} and {1} success'.format(newObj + self.nameCut(tempAttr[0], 2), constNam + i))
                except:
                    mc.disconnectAttr(constNam + i, oldObj + self.nameCut(tempAttr[0], 2))
                    mc.connectAttr(constNam + i, newObj + self.nameCut(tempAttr[0], 2), f=True)
                    print('connect {0} and {1} success'.format(constNam + i, oldObj + self.nameCut(tempAttr[0], 2)))

        elif len(AttrList) == 1:
            if AttrList[0] == 'p':
                tempnewConst = mc.parentConstraint(oldObj, newObj, mo=True)
            elif AttrList[0] == 's':
                tempnewConst = mc.scaleConstraint(oldObj, newObj, mo=True)
            self.newConst.extend(tempnewConst)

    def constFrameTrans(self):
        if self.oldConst:
            for i in range(len(self.oldConst)):
                attrList1 = mc.listAttr(self.oldConst[i], k=True, v=True, ud=True)
                attrList2 = mc.listAttr(self.newConst[i], k=True, v=True, ud=True)
                for j in range(len(attrList1)):
                    tempFrameList = mc.keyframe(self.oldConst, attribute=attrList1[j], query=True)
                    if tempFrameList:
                        for f in tempFrameList:
                            try:
                                tempValue = mc.keyframe(self.oldConst[i] + '.' + attrList1[j], query=True, vc=True,
                                                        t=(f, f))
                                tempValue1 = Decimal(str(tempValue[0])).quantize(Decimal('0.00'))
                                inAng = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ia=True,
                                                      t=(f, f))
                                inTT = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, itt=True,
                                                     t=(f, f))
                                outAng = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, oa=True,
                                                       t=(f, f))
                                outTT = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ott=True,
                                                      t=(f, f))
                                inW = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, iw=True,
                                                    t=(f, f))
                                outW = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ow=True,
                                                     t=(f, f))

                                mc.setKeyframe(self.newConst[i], t=(f, f), at=attrList2[j], v=float(tempValue1))
                                mc.keyTangent(self.newConst[i], edit=True, t=(f, f), at=attrList2[j], ia=inAng[0],
                                              oa=outAng[0], iw=inW[0], ow=outW[0], itt=inTT[0], ott=outTT[0])
                            except:
                                print('约束{0}属性{1}帧数{2}传递失败'.format(self.oldConst[i], attrList1[j], f))
                    else:
                        try:
                            val = mc.getAttr(self.oldConst[i] + '.' + attrList1[j])
                            mc.setAttr(self.newConst[i] + '.' + attrList2[j], val)
                        except:
                            print('数值传递约束属性{0}.{1}出错'.format(self.oldConst[i], attrList1[j]))

    def delNew(self):
        if self.newDelConst:
            for i in self.newDelConst:
                mc.delete(i)
        mc.delete(self.polarBear)

    def unloadRef(self,refNode):
        mc.file(ur = refNode)

    def clostMaya(self):
        mc.quit(force=True)

    def output(self):
        pass

    def input(self):
        pass






最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容