Ejemplo n.º 1
0
    def processUVs(self, fbxMesh, usdMesh, vertexIndices):
        for layerIdx in xrange(fbxMesh.GetLayerCount()):
            fbxLayerUVs = fbxMesh.GetLayer(
                layerIdx).GetUVs()  # get diffuse texture uv-s
            if fbxLayerUVs is None:
                continue

            uvs = []
            uvArray = fbxLayerUVs.GetDirectArray()
            for i in xrange(uvArray.GetCount()):
                uv = uvArray.GetAt(i)
                uvs.append(Gf.Vec2f(uv[0], uv[1]))
            if not any(uvs):
                continue

            indices = self.getIndicesWithLayerElements(fbxMesh, fbxLayerUVs)
            interpolation = self.getInterpolationWithLayerElements(fbxLayerUVs)

            texCoordSet = 'st'
            uvSets = fbxMesh.GetLayer(layerIdx).GetUVSets()
            if len(uvSets) > 0:
                fbxLayerElementUV = fbxMesh.GetLayer(layerIdx).GetUVSets()[0]
                texCoordSet = str(fbxLayerElementUV.GetName())
                if layerIdx == 0 or texCoordSet == '' or texCoordSet == 'default':
                    texCoordSet = 'st'
                else:
                    texCoordSet = usdUtils.makeValidIdentifier(texCoordSet)

            uvPrimvar = usdMesh.CreatePrimvar(texCoordSet,
                                              Sdf.ValueTypeNames.Float2Array,
                                              interpolation)
            uvPrimvar.Set(uvs)
            if len(indices) != 0:
                uvPrimvar.SetIndices(Vt.IntArray(indices))
Ejemplo n.º 2
0
    def processSkinnedMeshes(self):
        for fbxNode, skeleton in self.skeletonByNode.iteritems():
            fbxSkin = self.getFbxSkin(fbxNode)
            if skeleton is None:
                if fbxSkin is None:
                    continue
                skin = self.fbxSkinToSkin[fbxSkin]
                skeleton = skin.skeleton

            nodeName = usdUtils.makeValidIdentifier(
                fbxNode.GetName().split(":")[-1])
            newPath = skeleton.sdfPath + '/' + nodeName
            if newPath in self.nodePaths:
                newPath = newPath + str(self.nodeId)
                self.nodeId = self.nodeId + 1
            self.nodePaths[newPath] = newPath
            self.processMesh(fbxNode, newPath, skeleton, '')
Ejemplo n.º 3
0
    def bindMaterials(self, fbxMesh, usdMesh):
        for layerIdx in xrange(fbxMesh.GetLayerCount()):
            fbxLayerMaterials = fbxMesh.GetLayer(layerIdx).GetMaterials()
            if not fbxLayerMaterials:
                continue

            # looks like there is a bug in FBX SDK:
            # GetDirectArray() does not work if .GetCount() has not been called
            materialsCount = fbxLayerMaterials.GetDirectArray().GetCount()

            if fbxLayerMaterials.GetIndexArray().GetCount(
            ) > 1 and fbxLayerMaterials.GetMappingMode(
            ) == fbx.FbxLayerElement.eByPolygon:
                # subsets
                subsets = [[] for i in range(materialsCount)]
                for polygonIdx in range(
                        fbxLayerMaterials.GetIndexArray().GetCount()):
                    materialIndex = fbxLayerMaterials.GetIndexArray().GetAt(
                        polygonIdx)
                    subsets[materialIndex].append(polygonIdx)

                bindingAPI = UsdShade.MaterialBindingAPI(usdMesh)
                for materialIndex in range(materialsCount):
                    facesCount = len(subsets[materialIndex])
                    if facesCount > 0:
                        fbxMaterial = fbxLayerMaterials.GetDirectArray().GetAt(
                            materialIndex)
                        materialName = usdUtils.makeValidIdentifier(
                            fbxMaterial.GetName())
                        subsetName = materialName + '_subset'
                        if self.verbose:
                            print '  subset:', subsetName, 'faces:', facesCount
                        usdSubset = UsdShade.MaterialBindingAPI.CreateMaterialBindSubset(
                            bindingAPI, subsetName,
                            Vt.IntArray(subsets[materialIndex]))
                        usdMaterial = self.usdMaterials[fbxMaterial.GetName()]
                        UsdShade.MaterialBindingAPI(usdSubset).Bind(
                            usdMaterial)
            elif fbxLayerMaterials.GetIndexArray().GetCount() > 0:
                # one material for whole mesh
                fbxMaterial = fbxLayerMaterials.GetDirectArray().GetAt(0)
                if fbxMaterial is not None and fbxMaterial.GetName(
                ) in self.usdMaterials:
                    usdMaterial = self.usdMaterials[fbxMaterial.GetName()]
                    UsdShade.Material.Bind(usdMaterial, usdMesh.GetPrim())
Ejemplo n.º 4
0
 def getTextureProperties(self, materialProperty):
     if materialProperty.GetSrcObjectCount(
             fbx.FbxCriteria.ObjectType(fbx.FbxFileTexture.ClassId)) > 0:
         fbxFileTexture = materialProperty.GetSrcObject(
             fbx.FbxCriteria.ObjectType(fbx.FbxFileTexture.ClassId), 0)
         texCoordSet = 'st'
         if fbxFileTexture.UVSet is not None:
             texCoordSet = str(fbxFileTexture.UVSet.Get())
             if texCoordSet == '' or texCoordSet == 'default':
                 texCoordSet = 'st'
             else:
                 texCoordSet = usdUtils.makeValidIdentifier(texCoordSet)
         wrapS = 'repeat'
         wrapT = 'repeat'
         if fbxFileTexture.GetWrapModeU() == fbx.FbxTexture.eClamp:
             wrapS = 'clamp'
         if fbxFileTexture.GetWrapModeV() == fbx.FbxTexture.eClamp:
             wrapT = 'clamp'
         return fbxFileTexture.GetFileName(), texCoordSet, wrapS, wrapT
     elif materialProperty.GetSrcObjectCount(
             fbx.FbxCriteria.ObjectType(fbx.FbxLayeredTexture.ClassId)) > 0:
         pass
     return '', 'st', 'repeat', 'repeat'
Ejemplo n.º 5
0
    def createMesh(self, geomPath, group, groupName, usdStage):
        if len(group.faceVertexCounts) == 0:
            return False

        groupName = usdUtils.makeValidIdentifier(groupName)
        if self.verbose:
            print '  creating USD mesh:', groupName, ('(subsets: ' + str(len(group.subsets)) + ')' if len(group.subsets) > 1 else '')
        usdMesh = UsdGeom.Mesh.Define(usdStage, geomPath + '/' + groupName)
        usdMesh.CreateSubdivisionSchemeAttr(UsdGeom.Tokens.none)

        usdMesh.CreateFaceVertexCountsAttr(group.faceVertexCounts)

        # vertices
        minVertexIndex = min(group.vertexIndices)
        maxVertexIndex = max(group.vertexIndices)

        groupVertices = self.vertices[minVertexIndex:maxVertexIndex+1]
        usdMesh.CreatePointsAttr(groupVertices)
        if minVertexIndex == 0: # optimization
            usdMesh.CreateFaceVertexIndicesAttr(group.vertexIndices)
        else:
            usdMesh.CreateFaceVertexIndicesAttr(map(lambda x: x - minVertexIndex, group.vertexIndices))

        extent = Gf.Range3f()
        for pt in groupVertices:
            extent.UnionWith(Gf.Vec3f(pt))
        usdMesh.CreateExtentAttr([extent.GetMin(), extent.GetMax()])

        # vertex colors
        if len(self.colors) == len(self.vertices):
            colorAttr = usdMesh.CreateDisplayColorPrimvar(UsdGeom.Tokens.vertex)
            colorAttr.Set(self.colors[minVertexIndex:maxVertexIndex+1])

        # texture coordinates
        minUvIndex = min(group.uvIndices)
        maxUvIndex = max(group.uvIndices)

        if minUvIndex >= 0:
            if group.uvsHaveOwnIndices:
                uvPrimvar = usdMesh.CreatePrimvar('st', Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.faceVarying)
                uvPrimvar.Set(self.uvs[minUvIndex:maxUvIndex+1])
                if minUvIndex == 0:  # optimization
                    uvPrimvar.SetIndices(Vt.IntArray(group.uvIndices))
                else:
                    uvPrimvar.SetIndices(Vt.IntArray(map(lambda x: x - minUvIndex, group.uvIndices)))
            else:
                uvPrimvar = usdMesh.CreatePrimvar('st', Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.vertex)
                uvPrimvar.Set(self.uvs[minUvIndex:maxUvIndex+1])

        # normals
        minNormalIndex = min(group.normalIndices)
        maxNormalIndex = max(group.normalIndices)

        if minNormalIndex >= 0:
            if group.normalsHaveOwnIndices:
                normalPrimvar = usdMesh.CreatePrimvar('normals', Sdf.ValueTypeNames.Normal3fArray, UsdGeom.Tokens.faceVarying)
                normalPrimvar.Set(self.normals[minNormalIndex:maxNormalIndex+1])
                if minNormalIndex == 0:  # optimization
                    normalPrimvar.SetIndices(Vt.IntArray(group.normalIndices))
                else:
                    normalPrimvar.SetIndices(Vt.IntArray(map(lambda x: x - minNormalIndex, group.normalIndices)))
            else:
                normalPrimvar = usdMesh.CreatePrimvar('normals', Sdf.ValueTypeNames.Normal3fArray, UsdGeom.Tokens.vertex)
                normalPrimvar.Set(self.normals[minNormalIndex:maxNormalIndex+1])

        # materials
        if len(group.subsets) == 1:
            materialIndex = group.subsets[0].materialIndex
            if self.verbose:
                if 0 <= materialIndex and materialIndex < len(self.usdMaterials):
                    print usdUtils.makeValidIdentifier(self.materials[materialIndex])
                else:
                    print 'defaultMaterial'
            UsdShade.MaterialBindingAPI(usdMesh).Bind(self.getUsdMaterial(materialIndex))
        else:
            bindingAPI = UsdShade.MaterialBindingAPI(usdMesh)
            for subset in group.subsets:
                materialIndex = subset.materialIndex
                if len(subset.faces) > 0:
                    materialName = 'defaultMaterial'
                    if 0 <= materialIndex and materialIndex < len(self.usdMaterials):
                        materialName = usdUtils.makeValidIdentifier(self.materials[materialIndex])
                    subsetName = materialName + 'Subset'
                    if self.verbose:
                        print '  subset:', subsetName, 'faces:', len(subset.faces)
                    usdSubset = UsdShade.MaterialBindingAPI.CreateMaterialBindSubset(bindingAPI, subsetName, Vt.IntArray(subset.faces))
                    UsdShade.MaterialBindingAPI(usdSubset).Bind(self.getUsdMaterial(materialIndex))
Ejemplo n.º 6
0
    def processNode(self, fbxNode, path, underSkeleton, indent):
        nodeName = usdUtils.makeValidIdentifier(
            fbxNode.GetName().split(":")[-1])
        newPath = path + '/' + nodeName
        if newPath in self.nodePaths:
            newPath = newPath + str(self.nodeId)
            self.nodeId = self.nodeId + 1

        fbxAttributeType = fbx.FbxNodeAttribute.eNone
        fbxNodeAttribute = fbxNode.GetNodeAttribute()
        if fbxNodeAttribute:
            fbxAttributeType = fbxNodeAttribute.GetAttributeType()

        if fbx.FbxNodeAttribute.eSkeleton == fbxAttributeType:
            if fbxNodeAttribute.IsSkeletonRoot():
                skeleton = self.skinning.findSkeletonByRoot(fbxNode)
                if skeleton is None:
                    skeleton = self.skinning.findSkeletonByJoint(fbxNode)
                if skeleton is not None:
                    skeleton.makeUsdSkeleton(self.usdStage, newPath,
                                             self.nodeManager)
                    if self.verbose:
                        print indent + "SkelRoot:", nodeName
                    underSkeleton = skeleton

        if underSkeleton and self.getFbxMesh(fbxNode) is not None:
            self.skeletonByNode[fbxNode] = underSkeleton
        elif self.getFbxSkin(fbxNode) is not None:
            self.skeletonByNode[fbxNode] = None
        else:
            # if we have a geometric transformation we shouldn't propagate it to node's children
            usdNode = None
            hasGeometricTransform = self.hasGeometricTransform(fbxNode)
            if underSkeleton is None and hasGeometricTransform and underSkeleton is None:
                usdNode = UsdGeom.Xform.Define(self.usdStage, newPath)
                geometryPath = newPath + '/' + nodeName + '_geometry'
            else:
                geometryPath = newPath

            usdGeometry = None
            if (fbx.FbxNodeAttribute.eMesh == fbxAttributeType
                    or fbx.FbxNodeAttribute.eSubDiv == fbxAttributeType):
                usdGeometry = self.processMesh(fbxNode, geometryPath,
                                               underSkeleton, indent)

            if underSkeleton is None:
                if usdGeometry is None:
                    usdGeometry = UsdGeom.Xform.Define(self.usdStage,
                                                       geometryPath)

                self.nodePaths[newPath] = newPath
                if hasGeometricTransform:
                    self.setNodeTransforms(fbxNode, usdNode)
                    self.setGeometricTransform(fbxNode, usdGeometry)
                    self.processNodeAnimations(fbxNode, usdNode)
                else:
                    self.setNodeTransforms(fbxNode, usdGeometry)
                    self.processNodeAnimations(fbxNode, usdGeometry)

        # process child nodes recursively
        if underSkeleton is not None:
            newPath = path  # keep meshes directly under SkelRoot scope

        for childIdx in xrange(fbxNode.GetChildCount()):
            self.processNode(fbxNode.GetChild(childIdx), newPath,
                             underSkeleton, indent + '  ')
Ejemplo n.º 7
0
 def overrideGetName(self, fbxNode):
     return usdUtils.makeValidIdentifier(fbxNode.GetName().split(":")[-1])
Ejemplo n.º 8
0
def getName(dict, template, id):
    if 'name' in dict and len(dict['name']) != 0:
        validName = usdUtils.makeValidIdentifier(dict['name'])
        if validName != 'defaultIdentifier':
            return validName
    return template + str(id)