示例#1
0
    def testBadNames(self):
        '''Test using bad prim and variant names.

        Add a Maya Reference using a bad Maya Reference prim name and
        bad Variant Set and Variant name.
        '''
        kDefaultPrimName = mayaRefUtils.defaultMayaReferencePrimName()

        # Create another prim to test sanitizing variant set and name.
        primTestSanitizeVariant = self.stage.DefinePrim(
            '/Test_SanitizeVariant', 'Xform')
        primPathStr = self.proxyShapePathStr + ',/Test_SanitizeVariant'

        kBadPrimName = ('3' + kDefaultPrimName + '$')
        kGoodPrimName = Tf.MakeValidIdentifier(kBadPrimName)
        kBadVariantSetName = 'No Spaces or Special#Chars'
        kGoodVariantSetName = Tf.MakeValidIdentifier(kBadVariantSetName)
        kBadVariantName = '3no start digits'
        kGoodVariantName = Tf.MakeValidIdentifier(kBadVariantName)
        mayaRefPrim = mayaUsdAddMayaReference.createMayaReferencePrim(
            primPathStr,
            self.mayaSceneStr,
            self.kDefaultNamespace,
            mayaReferencePrimName=kBadPrimName,
            variantSet=(kBadVariantSetName, kBadVariantName))

        # Make sure the prim has the variant set and variant with
        # the sanitized names.
        self.assertTrue(primTestSanitizeVariant.HasVariantSets())
        vset = primTestSanitizeVariant.GetVariantSet(kGoodVariantSetName)
        self.assertTrue(vset.IsValid())
        self.assertEqual(vset.GetName(), kGoodVariantSetName)
        self.assertTrue(vset.GetVariantNames())
        self.assertTrue(vset.HasAuthoredVariant(kGoodVariantName))
        self.assertEqual(vset.GetVariantSelection(), kGoodVariantName)

        # Verify that the prim was created with the good name.
        self.assertTrue(mayaRefPrim.IsValid())
        self.assertEqual(str(mayaRefPrim.GetName()), kGoodPrimName)
        self.assertEqual(mayaRefPrim,
                         primTestSanitizeVariant.GetChild(kGoodPrimName))
        self.assertTrue(mayaRefPrim.GetPrimTypeInfo().GetTypeName(),
                        'MayaReference')

        # Adding a Maya Reference with the same name should produce an error.
        mayaRefPrim = mayaUsdAddMayaReference.createMayaReferencePrim(
            primPathStr,
            self.mayaSceneStr,
            self.kDefaultNamespace,
            mayaReferencePrimName=kGoodPrimName)
        self.assertFalse(mayaRefPrim.IsValid())
示例#2
0
    def test_Identifiers(self):
        self.assertFalse(Tf.IsValidIdentifier(''))
        self.assertTrue(Tf.IsValidIdentifier('hello9'))
        self.assertFalse(Tf.IsValidIdentifier('9hello'))
        self.assertTrue(Tf.IsValidIdentifier('hello_world'))
        self.assertTrue(Tf.IsValidIdentifier('HELLO_WORLD'))
        self.assertTrue(Tf.IsValidIdentifier('hello_world_1234'))
        self.assertFalse(Tf.IsValidIdentifier('hello_#world#_1234'))
        self.assertFalse(Tf.IsValidIdentifier('h e l l o'))

        self.assertEqual(Tf.MakeValidIdentifier(''), '_')
        self.assertEqual(Tf.MakeValidIdentifier('hello9'), 'hello9')
        self.assertEqual(Tf.MakeValidIdentifier('9hello'), '_hello')
        self.assertEqual(Tf.MakeValidIdentifier('hello_#world#_1234'),
                         'hello__world__1234')
        self.assertFalse(Tf.IsValidIdentifier('h e l l o'), 'h_e_l_l_o')
        self.assertFalse(Tf.IsValidIdentifier('!@#$%'), '_____')
 def _set_scene_camera(self, renderer, scene):
     if scene.hdusd.final.nodetree_camera != '' and scene.hdusd.final.data_source:
         usd_camera = UsdAppUtils.GetCameraAtPath(self.stage, scene.hdusd.final.nodetree_camera)
     else:
         usd_camera = UsdAppUtils.GetCameraAtPath(self.stage, Tf.MakeValidIdentifier(scene.camera.data.name))
    
     gf_camera = usd_camera.GetCamera(scene.frame_current)
     renderer.SetCameraState(gf_camera.frustum.ComputeViewMatrix(),
                             gf_camera.frustum.ComputeProjectionMatrix())
示例#4
0
文件: makeCard.py 项目: drwave/camar
def makeMaterial(parentPath, imgFile, stage):
    newName = Tf.MakeValidIdentifier("Material_" + imgFile)
    mPath = os.path.join(parentPath, newName)
    mSchema = UsdShade.Material.Define(stage, mPath)
    mSurface = mSchema.CreateOutput("surface", Sdf.ValueTypeNames.Token)
    diffuseColor = createPreviewSurfaceShader(mPath, mSurface, stage)
    uv = createPrimvarShader(mPath, stage)
    createTextureShader(mPath, imgFile, diffuseColor, uv, stage)
    return Sdf.Path(mPath)
def variantNameTextChanged(variantName):
    # The text field cannot be empty. Reset to default value if it is.
    if not variantName:
        cmds.textField('variantNameText',
                       edit=True,
                       text=kDefaultCacheVariantName)
    else:
        # Make sure the name user entered doesn't contain any invalid characters.
        validatedName = Tf.MakeValidIdentifier(variantName)
        if validatedName != variantName:
            cmds.textField('variantNameText', edit=True, text=validatedName)
示例#6
0
    def convert_to_usd_friendly_node_name(name):
        """Format a glTF name to make it more USD friendly

        Arguments:
            name {str} -- glTF node name

        Returns:
            str -- USD friendly name
        """

        return Tf.MakeValidIdentifier(name)
示例#7
0
文件: tools.py 项目: Vochsel/fspy-USD
def convert(filepath, output, scope_name = "/Cameras/test", aperture_width = 36):
    try:
        # Get fSpy data
        project = fspy.Project(filepath)
        camera_parameters = project.camera_parameters

        # Setup USD scene

        stage = Usd.Stage.CreateInMemory()

        # Setup camera scope

        cameras_scope = Sdf.Path(scope_name)

        for prim in cameras_scope.GetAncestorsRange():
            xform = UsdGeom.Xform.Define(stage, prim)

        camera = UsdGeom.Camera.Define(stage, cameras_scope.AppendChild( Tf.MakeValidIdentifier(project.file_name) ))

        # - Transform
        matrix = Gf.Matrix4d(camera_parameters.camera_transform).GetTranspose()
        rotMat = Gf.Matrix4d(1.0).SetRotate(Gf.Rotation(Gf.Vec3d(1, 0, 0), -90.0))
        matrix = matrix * rotMat
        camera.AddTransformOp().Set(matrix)

        # - Apperture Size

        hfov = math.degrees(camera_parameters.fov_horiz)
        hfov = math.degrees(camera_parameters.fov_verti)

        width = camera_parameters.image_width
        height = camera_parameters.image_height
    
        aspectRatio = width/height
        iaspectRatio = height/width

        # TODO: We likely need to get this from somewhere
        apWidth = aperture_width
        apHeight = apWidth * iaspectRatio

        camera.CreateHorizontalApertureAttr().Set(apWidth)
        camera.CreateVerticalApertureAttr().Set(apHeight)

        # - Focal Length
        focalLength = (0.5*apHeight)/math.tan((0.5*hfov)/57.296)

        camera.CreateFocalLengthAttr().Set(focalLength)

        print(stage.ExportToString())
        stage.Export(output)
    except Exception as e:
        print("Couldnt convert: " + str(e))
        pass
示例#8
0
    def render(self, depsgraph):
        if not self.is_synced:
            return

        scene = depsgraph.scene
        width, height = scene.render.resolution_x, scene.render.resolution_y

        renderer = UsdImagingLite.Engine()
        renderer.SetRendererPlugin('HdRprPlugin')
        renderer.SetRendererSetting('rpr:maxSamples', self.SAMPLES_NUMBER)
        renderer.SetRendererSetting('rpr:core:renderQuality', 'Northstar')
        renderer.SetRendererSetting('rpr:alpha:enable', False)
        renderer.SetRendererSetting('rpr:adaptiveSampling:minSamples', 16)
        renderer.SetRendererSetting('rpr:adaptiveSampling:noiseTreshold', 0.05)

        renderer.SetRenderViewport((0, 0, width, height))
        renderer.SetRendererAov('color')

        # setting camera
        usd_camera = UsdAppUtils.GetCameraAtPath(
            self.stage, Tf.MakeValidIdentifier(scene.camera.data.name))

        gf_camera = usd_camera.GetCamera()
        renderer.SetCameraState(gf_camera.frustum.ComputeViewMatrix(),
                                gf_camera.frustum.ComputeProjectionMatrix())

        params = UsdImagingLite.RenderParams()
        image = np.empty((width, height, 4), dtype=np.float32)

        def update_render_result():
            result = self.render_engine.begin_result(0, 0, width, height)
            render_passes = result.layers[0].passes
            render_passes.foreach_set('rect', image.flatten())
            self.render_engine.end_result(result)

        renderer.Render(self.stage.GetPseudoRoot(), params)

        while True:
            if self.render_engine.test_break():
                break

            if renderer.IsConverged():
                break

            renderer.GetRendererAov('color', image.ctypes.data)
            update_render_result()

        renderer.GetRendererAov('color', image.ctypes.data)
        update_render_result()

        # its important to clear data explicitly
        renderer = None
def sync(obj_prim, obj: bpy.types.Object, **kwargs):
    """Creates Usd camera from obj.data: bpy.types.Camera"""
    scene = kwargs['scene']
    screen_ratio = scene.render.resolution_x / scene.render.resolution_y

    camera = obj.data
    log("sync", camera)

    stage = obj_prim.GetStage()
    usd_camera = UsdGeom.Camera.Define(stage, obj_prim.GetPath().AppendChild(Tf.MakeValidIdentifier(camera.name)))

    settings = CameraData.init_from_camera(camera, obj.matrix_world, screen_ratio)
    settings.export(usd_camera)
示例#10
0
    def testRenameSpecialCharacter(self):
        # open twoSpheres.ma scene in testSamples
        mayaUtils.openTwoSpheresScene()

        # clear selection to start off
        cmds.select(clear=True)

        # select a USD object.
        mayaPathSegment = mayaUtils.createUfePathSegment(
            '|usdSphereParent|usdSphereParentShape')
        usdPathSegment = usdUtils.createUfePathSegment('/sphereXform/sphere')
        basePath = ufe.Path([mayaPathSegment, usdPathSegment])
        usdSphereItem = ufe.Hierarchy.createItem(basePath)

        ufe.GlobalSelection.get().append(usdSphereItem)

        # get the USD stage
        stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

        # by default edit target is set to the Rootlayer.
        self.assertEqual(stage.GetEditTarget().GetLayer(),
                         stage.GetRootLayer())

        # rename with special chars
        newNameWithSpecialChars = '!@#%$@$=sph^e.re_*()<>}021|'
        cmds.rename(newNameWithSpecialChars)

        # get the prim
        pSphereItem = ufe.GlobalSelection.get().front()
        usdPrim = stage.GetPrimAtPath(str(pSphereItem.path().segments[1]))
        self.assertTrue(usdPrim)

        # prim names are not allowed to have special characters except '_'
        regex = re.compile('[@!#$%^&*()<>?/\|}{~:]')
        self.assertFalse(regex.search(usdPrim.GetName()))

        # rename starting with digits.
        newNameStartingWithDigit = '09123Potato'
        self.assertFalse(Tf.IsValidIdentifier(newNameStartingWithDigit))
        cmds.rename(newNameStartingWithDigit)

        # get the prim
        pSphereItem = ufe.GlobalSelection.get().front()
        usdPrim = stage.GetPrimAtPath(str(pSphereItem.path().segments[1]))
        self.assertTrue(usdPrim)

        # prim names are not allowed to start with digits
        newValidName = Tf.MakeValidIdentifier(newNameStartingWithDigit)
        self.assertEqual(usdPrim.GetName(), newValidName)
def primNameTextChanged(primName):
    # The text field cannot be empty. Reset to default value if it is.
    mayaRefPrimParent = _pulledMayaRefPrim.GetParent()
    if not primName:
        primName = mayaUsd.ufe.uniqueChildName(mayaRefPrimParent,
                                               kDefaultCachePrimName)
        cmds.textFieldGrp('primNameText', edit=True, text=primName)
    else:
        # Make sure the name user entered is unique and doesn't contain
        # any invalid characters.
        validatedName = Tf.MakeValidIdentifier(primName)
        validatedName = mayaUsd.ufe.uniqueChildName(mayaRefPrimParent,
                                                    validatedName)
        if validatedName != primName:
            cmds.textFieldGrp('primNameText', edit=True, text=validatedName)
示例#12
0
文件: makeCard.py 项目: drwave/camar
def makeCard(topLevelName, imgFile, creditFile, width, height, upAxis, stage):
    cardPath = "/" + Tf.MakeValidIdentifier(topLevelName)
    cardSchema = UsdGeom.Xform.Define(stage, cardPath)
    prim = cardSchema.GetPrim()
    stage.SetDefaultPrim(prim)
    # we should also add info about the src image here as well...
    # I think we can add a "comment" which will show up
    prim.SetMetadata(Sdf.PrimSpec.KindKey, Kind.Tokens.component)
    material = makeMaterial(cardPath, imgFile, stage)
    materialBackSq = makeMaterial(cardPath, creditFile, stage)
    # we should replace the following single call with calls to
    # make 3 meshes
    frameW = 1
    makeMesh(cardPath, width, height, upAxis, material, stage)
    makeMatte(cardPath, height, width, upAxis, material, stage)
    makeFrame(cardPath, height, width, upAxis, frameW, material, stage)
    
    makeBackSq(cardPath, height, width, upAxis, frameW, materialBackSq, stage)
示例#13
0
def UpdateSchemaWithSdrNode(schemaLayer, sdrNode, renderContext="",
        overrideIdentifier=""):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. 

    A renderContext can be provided which is used in determining the
    shaderId namespace, which follows the pattern: 
    "<renderContext>:<SdrShaderNodeContext>:shaderId". Note that we are using a
    node's context (SDR_NODE_CONTEXT_TOKENS) here to construct the shaderId
    namespace, so shader parsers should make sure to use appropriate
    SDR_NODE_CONTEXT_TOKENS in the node definitions.

    overrideIdentifier parameter is the identifier which should be used when 
    the identifier of the node being processed differs from the one Sdr will 
    discover at runtime, such as when this function is def a node constructed 
    from an explicit asset path. This should only be used when clients know the 
    identifier being passed is the true identifier which sdr Runtime will 
    provide when querying using GetShaderNodeByIdentifierAndType, etc.

    It consumes the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (Note that this does not support
          multiple apply schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an API schema or 
          "Typed" for a concrete scheme.
        - "apiSchemasForAttrPruning": A list of core API schemas which will be
          composed together and any shared shader property from this prim
          definition is pruned from the resultant schema. 
        - "typedSchemaForAttrPruning": A core typed schema which will be
          composed together with the apiSchemasForAttrPruning and any shared 
          shader property from this prim definition is pruned from the 
          resultant schema. If no typedSchemaForAttrPruning is provided then 
          only the apiSchemasForAttrPruning are composed to create a prim 
          definition. This will only be used when creating an APISchema.
        - "apiSchemaAutoApplyTo": The schemas to which the sdrNode populated 
          API schema will autoApply to.
        - "apiSchemaCanOnlyApplyTo": If specified, the API schema generated 
          from the sdrNode can only be validly applied to this set of schemas.
        - "providesUsdShadeConnectableAPIBehavior": Used to enable a 
          connectability behavior for an API schema.
        - "isUsdShadeContainer": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Marks the
          connectable prim as a UsdShade container type.
        - "requiresUsdShadeEncapsulation": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Configures the
          UsdShade encapsulation rules governing its connectableBehavior.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.
        - "schemaPropertyNSPrefixOverride": Node level metadata which can drive
          all node's properties namespace prefix. This can be useful for
          non connectable nodes which should not get UsdShade inputs and outputs
          namespace prefix.

    Property Level Metadata:
        - "usdVariability": Property level metadata which specifies a specific 
          sdrNodeProperty should have its USD variability set to Uniform or 
          Varying
        - "usdSuppressProperty": A property level metadata which determines if 
          the property should be suppressed from translation from args to 
          property spec.
        - "propertyNSPrefixOverride": Provides a way to override a property's
          namespace from the default (inputs:/outputs:) or from a node's
          schemaPropertyNSPrefixOverride metadata.

    Sdr Property Metadata to SdfPropertySpec Translations
        - A "null" value for Widget sdrProperty metadata translates to 
          SdfPropertySpec Hidden metadata.
        - SdrProperty's Help metadata (Label metadata if Help metadata not 
          provided) translates to SdfPropertySpec's Documentation string 
          metadata.
        - SdrProperty's Page metadata translates to SdfPropertySpec's
          DisplayGroup metadata.
        - SdrProperty's Label metadata translates to SdfPropertySpec's
          DisplayName metadata.
        - SdrProperty's Options translates to SdfPropertySpec's AllowedTokens.
        - SdrProperty's Default value translates to SdfPropertySpec's Default
          value.
        - Connectable input properties translates to InterfaceOnly
          SdfPropertySpec's CONNECTABILITY.
    """

    import distutils.util
    import os

    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if sdrNode is None:
        # This is a workaround to iterate through invalid sdrNodes (nodes not 
        # having any input or output properties). Currently these nodes return
        # false when queried for IsValid().
        # Refer: pxr/usd/ndr/node.h#140-149
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if SchemaDefiningKeys.SCHEMA_NAME not in sdrNodeMetadata:
        Tf.Warn("Sdr Node (%s) does not define a schema name metadata." \
                %(sdrNode.GetName()))
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError("schemaName (%s) is an invalid identifier; "
                "Provide a valid USD identifer for schemaName, example (%s) "
                %(schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if SchemaDefiningKeys.TF_TYPENAME_SUFFIX in sdrNodeMetadata:
        tfTypeNameSuffix = sdrNodeMetadata[SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if SchemaDefiningKeys.SCHEMA_KIND not in sdrNodeMetadata:
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiple apply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
        "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
            Tf.Warn("node metadata implies the generated schema being created "
            "is an API schema, fixing tfTypeNameSuffix to reflect that")
            tfTypeNameSuffix = tfTypeNameSuffix + \
                    SchemaDefiningMiscConstants.API_STRING

    if SchemaDefiningKeys.SCHEMA_BASE not in sdrNodeMetadata:
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO in sdrNodeMetadata:
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    apiSchemaCanOnlyApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO in sdrNodeMetadata:
        apiSchemaCanOnlyApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO] \
                .split('|')

    providesUsdShadeConnectableAPIBehavior = False
    if SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR in \
            sdrNodeMetadata:
        providesUsdShadeConnectableAPIBehavior = \
            distutils.util.strtobool(sdrNodeMetadata[SchemaDefiningKeys. \
                PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR])

    apiSchemasForAttrPruning = None
    if SchemaDefiningKeys.API_SCHEMAS_FOR_ATTR_PRUNING in sdrNodeMetadata:
        apiSchemasForAttrPruning = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMAS_FOR_ATTR_PRUNING] \
                .split('|')

    typedSchemaForAttrPruning = ""
    if isAPI and \
            SchemaDefiningKeys.TYPED_SCHEMA_FOR_ATTR_PRUNING in sdrNodeMetadata:
        typedSchemaForAttrPruning = \
            sdrNodeMetadata[SchemaDefiningKeys.TYPED_SCHEMA_FOR_ATTR_PRUNING]

    schemaPropertyNSPrefixOverride = None
    if SchemaDefiningKeys.SCHEMA_PROPERTY_NS_PREFIX_OVERRIDE in sdrNodeMetadata:
        schemaPropertyNSPrefixOverride = \
            sdrNodeMetadata[ \
                SchemaDefiningKeys.SCHEMA_PROPERTY_NS_PREFIX_OVERRIDE]

    usdSchemaReg = Usd.SchemaRegistry()

    # determine if the node being processed provides UsdShade-Connectability, 
    # this helps in determining what namespace to use and also to report error 
    # if a non-connectable node has outputs properties, which is malformed.
    # - Does the node derive from a schemaBase which provides connectable
    # behavior. Warn if schemaPropertyNSPrefixOverride is also specified, as 
    # these metadata won't be used.
    # - If no schemaBase then we default to UsdShade connectable node's 
    # inputs:/outputs: namespace prefix, unless schemaPropertyNSPrefixOverride 
    # is provided. 
    # - We also report an error if schemaPropertyNSPrefixOverride is provided 
    # and an output property is found on the node being processed.
    schemaBaseProvidesConnectability = UsdShade.ConnectableAPI. \
            HasConnectableAPI(usdSchemaReg.GetTypeFromName(schemaBase))

    if (len(sdrNode.GetOutputNames()) > 0 and \
            schemaPropertyNSPrefixOverride is not None and \
            not _IsNSPrefixConnectableAPICompliant( \
                schemaPropertyNSPrefixOverride)):
        Tf.RaiseRuntimeError("Presence of (%s) output parameters contradicts " \
            "the presence of schemaPropertyNSPrefixOverride (\"%s\"), as it " \
            "is illegal for non-connectable nodes to contain output " \
            "parameters, or shader nodes' outputs to not have the \"outputs\"" \
            "namespace prefix." %(len(sdrNode.GetOutputNames()), \
            schemaPropertyNSPrefixOverride))

    if (schemaBaseProvidesConnectability and \
            schemaPropertyNSPrefixOverride is not None and \
            not _IsNSPrefixConnectableAPICompliant( \
                schemaPropertyNSPrefixOverride)):
        Tf.Warn("Node %s provides UsdShade-Connectability as it derives from " \
                "%s, schemaPropertyNSPrefixOverride \"%s\" will not be used." \
                %(schemaName, schemaBase, schemaPropertyNSPrefixOverride))
        # set schemaPropertyNSPrefixOverride to "inputs", assuming default 
        # UsdShade Connectability namespace prefix
        schemaPropertyNSPrefixOverride = "inputs"

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the 
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
            "" if isAPI else schemaName)
    
    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind 
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    if apiSchemaCanOnlyApplyTo:
        primSpecCustomData['apiSchemaCanOnlyApplyTo'] = \
            Vt.TokenArray(apiSchemaCanOnlyApplyTo)

    if providesUsdShadeConnectableAPIBehavior:
        extraPlugInfo = {
            SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR \
                    : True
        }
        for propKey in [SchemaDefiningKeys.IS_USD_SHADE_CONTAINER, \
                SchemaDefiningKeys.REQUIRES_USD_SHADE_ENCAPSULATION]:
            if propKey in sdrNodeMetadata:
                # Since we want to assign the types for these to bool and
                # because in python boolean type is a subset of int, we need to
                # do following instead of assign the propValue directly.
                propValue = distutils.util.strtobool(sdrNodeMetadata[propKey])
                extraPlugInfo[propKey] = bool(propValue)

        primSpecCustomData['extraPlugInfo'] = extraPlugInfo

    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from a prim definition generated by composing apiSchemas
    # provided by apiSchemasForAttrPruning metadata.
    primDefForAttrPruning = None
    if apiSchemasForAttrPruning:
        primDefForAttrPruning = usdSchemaReg.BuildComposedPrimDefinition(
                typedSchemaForAttrPruning, apiSchemasForAttrPruning)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName), 
                primDefForAttrPruning, schemaPropertyNSPrefixOverride)

    # Create attrSpecs from output parameters
    # Note that we always want outputs: namespace prefix for output attributes.
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName), 
                primDefForAttrPruning, UsdShade.Tokens.outputs[:-1], False)

    # Create token shaderId attrSpec -- only for shader nodes
    if (schemaBaseProvidesConnectability or \
            schemaPropertyNSPrefixOverride is None or \
            _IsNSPrefixConnectableAPICompliant(schemaPropertyNSPrefixOverride)):
        shaderIdAttrName = Sdf.Path.JoinIdentifier( \
                [renderContext, sdrNode.GetContext(), 
                    PropertyDefiningKeys.SHADER_ID])
        shaderIdAttrSpec = Sdf.AttributeSpec(primSpec, shaderIdAttrName,
                Sdf.ValueTypeNames.Token, Sdf.VariabilityUniform)

        # Since users shouldn't need to be aware of shaderId attribute, we put 
        # this in "Internal" displayGroup.
        shaderIdAttrSpec.displayGroup = \
                PropertyDefiningKeys.INTERNAL_DISPLAY_GROUP

        # Use the identifier if explicitly provided, (it could be a shader node
        # queried using an explicit path), else use sdrNode's registered 
        # identifier.
        nodeIdentifier = overrideIdentifier if overrideIdentifier else \
                sdrNode.GetIdentifier()
        shaderIdAttrSpec.default = nodeIdentifier

    # Extra attrSpec
    schemaBasePrimDefinition = \
        Usd.SchemaRegistry().FindConcretePrimDefinition(schemaBase)
    if schemaBasePrimDefinition and \
        SchemaDefiningMiscConstants.NodeDefAPI in \
        schemaBasePrimDefinition.GetAppliedAPISchemas():
            infoIdAttrSpec = Sdf.AttributeSpec(primSpec, \
                    UsdShade.Tokens.infoId, Sdf.ValueTypeNames.Token, \
                    Sdf.VariabilityUniform)
            infoIdAttrSpec.default = nodeIdentifier

    schemaLayer.Save()
def sdf_name(mat: bpy.types.Material, input_socket_key='Surface'):
    ret = Tf.MakeValidIdentifier(mat.name_full)
    if input_socket_key != 'Surface':
        ret += "/" + Tf.MakeValidIdentifier(mat.name_full)

    return ret
示例#15
0
def UpdateSchemaWithSdrNode(schemaLayer, sdrNode):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. It consume the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (note that this does not support
          multi-applied schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an api schema or 
          "Typed" for a concrete scheme.
        - "usdSchemaClass": Specified the equivalent schema directly generated
          by USD (sourceType: USD). This is used to make sure duplicate
          properties already specified in the USD schema are not populated in
          the new API schema. Note this is only used when we are dealing with an
          API schema.
        - "apiSchemaAutoApplyTo": The Schemas to which the sdrNode populated 
          (API) schema will autoApply to.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.

    Property Level Metadata:
        USD_VARIABILITY = A property level metadata, which specified a specific
        sdrNodeProperty should its usd variability set to Uniform or Varying.
    """
    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if not sdrNode:
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if not sdrNodeMetadata.has_key(SchemaDefiningKeys.SCHEMA_NAME):
        Tf.Warn("Sdr Node does not define a schema name metadata.")
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError(
            "schemaName (%s) is an invalid identifier; "
            "Provide a valid USD identifer for schemaName, example (%s) " %
            (schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if sdrNodeMetadata.has_key(SchemaDefiningKeys.TF_TYPENAME_SUFFIX):
        tfTypeNameSuffix = sdrNodeMetadata[
            SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if not sdrNodeMetadata.has_key(SchemaDefiningKeys.SCHEMA_KIND):
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiapply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
                "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created "
                "is an API schema, fixing tfTypeNameSuffix to reflect that")
        tfTypeNameSuffix = tfTypeNameSuffix + \
                SchemaDefiningMiscConstants.API_STRING

    if not sdrNodeMetadata.has_key(SchemaDefiningKeys.SCHEMA_BASE):
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if sdrNodeMetadata.has_key(SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO):
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    usdSchemaClass = None
    if isAPI and sdrNodeMetadata.has_key(SchemaDefiningKeys.USD_SCHEMA_CLASS):
        usdSchemaClass = \
            sdrNodeMetadata[SchemaDefiningKeys.USD_SCHEMA_CLASS]

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
                            "" if isAPI else schemaName)

    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from node directly generated from USD (sourceType: USD)
    # Use the usdSchemaClass tag when the generated schema being defined is an
    # API schema
    usdSchemaNode = None
    if usdSchemaClass:
        reg = Sdr.Registry()
        usdSchemaNode = reg.GetNodeByIdentifierAndType(
            usdSchemaClass, SchemaDefiningMiscConstants.USD_SOURCE_TYPE)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName),
                                         usdSchemaNode)

    # Create attrSpecs from output parameters
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName),
                                         usdSchemaNode, False)

    schemaLayer.Save()
 def _set_scene_camera(self, renderer, scene):
     usd_camera = UsdAppUtils.GetCameraAtPath(
         self.stage, Tf.MakeValidIdentifier(scene.camera.data.name))
     gf_camera = usd_camera.GetCamera()
     renderer.SetCameraState(gf_camera.frustum.ComputeViewMatrix(),
                             gf_camera.frustum.ComputeProjectionMatrix())
    def render(self, depsgraph):
        if not self.is_synced:
            return

        scene = depsgraph.scene
        width, height = scene.render.resolution_x, scene.render.resolution_y

        # uses for creating a transparent background icon to follow blender UI style
        is_preview_icon = width == 32 and height == 32

        self.renderer.SetRendererSetting('rpr:maxSamples', self.SAMPLES_NUMBER)
        self.renderer.SetRendererSetting('rpr:core:renderQuality', 'Northstar')
        self.renderer.SetRendererSetting('rpr:alpha:enable', is_preview_icon)
        self.renderer.SetRendererSetting('rpr:adaptiveSampling:minSamples', 16)
        self.renderer.SetRendererSetting('rpr:adaptiveSampling:noiseTreshold',
                                         0.05)

        self.renderer.ClearRendererAovs()
        self.renderer.SetRenderViewport((0, 0, width, height))
        self.renderer.SetRendererAov('color')

        # setting camera
        usd_camera = UsdAppUtils.GetCameraAtPath(
            self.stage, Tf.MakeValidIdentifier(scene.camera.data.name))

        gf_camera = usd_camera.GetCamera()
        self.renderer.SetCameraState(
            gf_camera.frustum.ComputeViewMatrix(),
            gf_camera.frustum.ComputeProjectionMatrix())

        params = UsdImagingLite.RenderParams()
        image = np.zeros((width, height, 4), dtype=np.float32)

        def update_render_result():
            result = self.render_engine.begin_result(0, 0, width, height)
            render_passes = result.layers[0].passes
            render_passes.foreach_set('rect', image.flatten())
            self.render_engine.end_result(result)

        while True:
            if self.render_engine.test_break():
                break

            try:
                self.renderer.Render(self.stage.GetPseudoRoot(), params)

            except Exception as e:
                # known RenderMan issue https://github.com/PixarAnimationStudios/USD/issues/1415
                if isinstance(
                        e, Tf.ErrorException
                ) and "Failed to load plugin 'rmanOslParser'" in str(e):
                    pass  # we won't log error "GL error: invalid operation"
                else:
                    log.error(e)

            if self.renderer.IsConverged():
                break

            self.renderer.GetRendererAov('color', image.ctypes.data)
            update_render_result()

        self.renderer.GetRendererAov('color', image.ctypes.data)
        update_render_result()
示例#18
0
def createMayaReferencePrim(
        ufePathStr,
        mayaReferencePath,
        mayaNamespace,
        mayaReferencePrimName=mayaRefUtils.defaultMayaReferencePrimName(),
        groupPrim=None,
        variantSet=None,
        mayaAutoEdit=kDefaultEditAsMayaData):
    '''Create a Maya reference prim and optional group prim parented to the argument path.
    Optionally create a variant set and name and placed the edits inside that variant.

    Naming of Maya Reference prim is supported, otherwise default name is used.

    The group prim is optional.

    The variant set and name are optional

    Parameters:
    -----------
    ufePathStr : str : Ufe PathString of parent prim to add Maya Reference
    mayaReferencePath : str : File path of Maya Reference (for attribute)
    mayaNamespace : str : Namespace (for attribute)
    mayaReferencePrimName : str [optional] : Name for the Maya Reference prim
    groupPrim : tuple(str,str,str) [optional] : The Group prim Name, Type & Kind to create
                                                Note: the name is optional and will be auto-computed
                                                      if empty or not provided.
                                                Note: Type and Kind are both mandatory, but Kind is
                                                      allowed to be empty string.
    variantSet : tuple(str,str) [optional] : The Variant Set Name and Variant Name to create

    Return:
    -------
    The Usd prim of the newly created Maya Reference or an invalid prim if there is an error.
    '''

    # Make sure the prim name is valid and doesn't already exist.
    parentPrim = mayaUsd.ufe.ufePathToPrim(ufePathStr)

    # There are special conditions when we are given the ProxyShape gateway node.
    ufePath = ufe.PathString.path(ufePathStr)
    isGateway = (ufePath.nbSegments() == 1)

    # Were we given a Group prim to create?
    groupPrimName = None
    groupPrimType = None
    groupPrimKind = None
    if groupPrim:
        if (len(groupPrim) == 2):
            groupPrimType, groupPrimKind = groupPrim
        elif (len(groupPrim) == 3):
            groupPrimName, groupPrimType, groupPrimKind = groupPrim

            # Make sure the input Group prim name doesn't exist already
            # and validate the input name.
            # Note: it is allowed to be input as empty in which case a default is used.
            if groupPrimName:
                checkGroupPrimName = mayaUsd.ufe.uniqueChildName(
                    parentPrim, groupPrimName)
                if checkGroupPrimName != groupPrimName:
                    errorMsgFormat = getMayaUsdLibString(
                        'kErrorGroupPrimExists')
                    errorMsg = cmds.format(errorMsgFormat,
                                           stringArg=(groupPrimName,
                                                      ufePathStr))
                    om.MGlobal.displayError(errorMsg)
                    return Usd.Prim()
                groupPrimName = Tf.MakeValidIdentifier(checkGroupPrimName)

        # If the group prim was either not provided or empty we use a default name.
        if not groupPrimName:
            groupPrimName = getDefaultGroupPrimName(parentPrim, mayaNamespace)

    # When the input is a gateway we cannot have in variant unless group is also given.
    if isGateway and variantSet and not groupPrimName:
        errorMsg = getMayaUsdLibString('kErrorCannotAddToProxyShape')
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()

    # Make sure the input Maya Reference prim name doesn't exist already
    # and validate the input name.
    # Note: if we are given a group prim to create, then we know that the
    #       Maya Reference prim name will be unique since it will be the
    #       only child (of the newly created group prim).
    checkName = mayaUsd.ufe.uniqueChildName(
        parentPrim,
        mayaReferencePrimName) if groupPrim is None else mayaReferencePrimName
    if checkName != mayaReferencePrimName:
        errorMsgFormat = getMayaUsdLibString('kErrorMayaRefPrimExists')
        errorMsg = cmds.format(errorMsgFormat,
                               stringArg=(mayaReferencePrimName, ufePathStr))
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()
    validatedPrimName = Tf.MakeValidIdentifier(checkName)

    # Extract the USD path segment from the UFE path and append the Maya
    # reference prim to it.
    parentPath = str(ufePath.segments[1]) if ufePath.nbSegments() > 1 else ''

    stage = mayaUsd.ufe.getStage(ufePathStr)

    # Optionally insert a Group prim as a parent of the Maya reference prim.
    groupPrim = None
    if groupPrimName:
        groupPath = Sdf.AssetPath(parentPath + '/' + groupPrimName)
        try:
            groupPrim = stage.DefinePrim(groupPath.path, groupPrimType)
        except (Tf.ErrorException):
            groupPrim = Usd.Prim()
        if not groupPrim.IsValid():
            errorMsgFormat = getMayaUsdLibString('kErrorCreatingGroupPrim')
            errorMsg = cmds.format(errorMsgFormat, stringArg=(ufePathStr))
            om.MGlobal.displayError(errorMsg)
            return Usd.Prim()
        if groupPrimKind:
            model = Usd.ModelAPI(groupPrim)
            model.SetKind(groupPrimKind)

    if groupPrim:
        primPath = Sdf.AssetPath(groupPrim.GetPath().pathString + '/' +
                                 validatedPrimName)
    else:
        primPath = Sdf.AssetPath(parentPath + '/' + validatedPrimName)

    # Were we given a Variant Set to create?
    variantSetName = None
    variantName = None
    if variantSet and (len(variantSet) == 2):
        variantSetName, variantName = variantSet
    if variantSetName and variantName:
        validatedVariantSetName = Tf.MakeValidIdentifier(variantSetName)
        validatedVariantName = Tf.MakeValidIdentifier(variantName)

        # If we created a group prim add the variant set there, otherwise add it
        # to the prim that corresponds to the input ufe path.
        variantPrim = groupPrim if groupPrim else mayaUsd.ufe.ufePathToPrim(
            ufePathStr)
        vset = variantPrim.GetVariantSet(validatedVariantSetName)
        vset.AddVariant(validatedVariantName)
        vset.SetVariantSelection(validatedVariantName)
        with vset.GetVariantEditContext():
            # Now all of our subsequent edits will go "inside" the
            # 'variantName' variant of 'variantSetName'.
            prim = createPrimAndAttributes(stage, primPath, mayaReferencePath,
                                           mayaNamespace, mayaAutoEdit)
    else:
        prim = createPrimAndAttributes(stage, primPath, mayaReferencePath,
                                       mayaNamespace, mayaAutoEdit)
    if prim is None or not prim.IsValid():
        errorMsgFormat = getMayaUsdLibString('kErrorCreatingMayaRefPrim')
        errorMsg = cmds.format(errorMsgFormat, stringArg=(ufePathStr))
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()

    return prim
示例#19
0
def sync(obj_prim,
         obj: bpy.types.Object,
         mesh: bpy.types.Mesh = None,
         **kwargs):
    """ Creates pyrpr.Shape from obj.data:bpy.types.Mesh """
    from .object import sdf_name

    if not mesh:
        mesh = obj.data

    log("sync", mesh, obj)

    data = MeshData.init_from_mesh(mesh, obj=obj)
    if not data:
        return

    stage = obj_prim.GetStage()

    usd_mesh = UsdGeom.Mesh.Define(
        stage,
        obj_prim.GetPath().AppendChild(Tf.MakeValidIdentifier(mesh.name)))

    usd_mesh.CreateDoubleSidedAttr(True)
    usd_mesh.CreateFaceVertexIndicesAttr(data.vertex_indices)
    usd_mesh.CreateFaceVertexCountsAttr(data.num_face_vertices)

    usd_mesh.CreateSubdivisionSchemeAttr(UsdGeom.Tokens.none)
    usd_mesh.SetNormalsInterpolation(UsdGeom.Tokens.faceVarying)

    points_attr = usd_mesh.CreatePointsAttr(data.vertices)
    normals_attr = usd_mesh.CreateNormalsAttr(data.normals)

    # here we can't just call mesh.calc_loop_triangles to update loops because Blender crashes
    armature = obj.find_armature()
    if armature and kwargs.get('is_use_animation', False):
        scene = kwargs.get('scene')

        frame_current = scene.frame_current

        frame_start = kwargs.get('frame_start') if kwargs.get(
            'is_restrict_frames') else scene.frame_start
        frame_end = kwargs.get('frame_end') if kwargs.get(
            'is_restrict_frames') else scene.frame_end

        for frame in range(frame_start, frame_end + 1):
            scene.frame_set(frame)
            new_mesh = obj.to_mesh()

            new_data = MeshData.init_from_mesh(new_mesh, obj=obj)

            points_attr.Set(new_data.vertices, frame)
            normals_attr.Set(new_data.normals, frame)

        obj.to_mesh_clear()

        scene.frame_set(frame_current)

    for name, uv_layer in data.uv_layers.items():
        uv_primvar = usd_mesh.CreatePrimvar(
            "st",  # default name, later we'll use sdf_path(name)
            Sdf.ValueTypeNames.TexCoord2fArray,
            UsdGeom.Tokens.faceVarying)
        uv_primvar.Set(uv_layer[0])
        uv_primvar.SetIndices(Vt.IntArray.FromNumpy(uv_layer[1]))

        break  # currently we use only first UV layer

    _assign_materials(obj_prim, obj.original, usd_mesh)
示例#20
0
def UpdateSchemaWithSdrNode(schemaLayer,
                            sdrNode,
                            renderContext="",
                            overrideIdentifier=""):
    """
    Updates the given schemaLayer with primSpec and propertySpecs from sdrNode
    metadata. 

    A renderContext can be provided which is used in determining the
    shaderId namespace, which follows the pattern: 
    "<renderContext>:<SdrShaderNodeContext>:shaderId". Note that we are using a
    node's context (SDR_NODE_CONTEXT_TOKENS) here to construct the shaderId
    namespace, so shader parsers should make sure to use appropriate
    SDR_NODE_CONTEXT_TOKENS in the node definitions.

    overrideIdentifier parameter is the identifier which should be used when 
    the identifier of the node being processed differs from the one Sdr will 
    discover at runtime, such as when this function is def a node constructed 
    from an explicit asset path. This should only be used when clients know the 
    identifier being passed is the true identifier which sdr Runtime will 
    provide when querying using GetShaderNodeByNameAndType, etc.

    It consumes the following attributes (that manifest as Sdr 
    metadata) in addition to many of the standard Sdr metadata
    specified and parsed (via its parser plugin).

    Node Level Metadata:
        - "schemaName": Name of the new schema populated from the given sdrNode
          (Required)
        - "schemaKind": Specifies the UsdSchemaKind for the schema being
          populated from the sdrNode. (Note that this does not support
          multiple apply schema kinds).
        - "schemaBase": Base schema from which the new schema should inherit
          from. Note this defaults to "APISchemaBase" for an API schema or 
          "Typed" for a concrete scheme.
        - "usdSchemaClass": Specifies the equivalent schema directly generated
          by USD (sourceType: USD). This is used to make sure duplicate
          properties already specified in the USD schema are not populated in
          the new API schema. Note this is only used when we are dealing with an
          API schema.
        - "apiSchemaAutoApplyTo": The schemas to which the sdrNode populated 
          API schema will autoApply to.
        - "apiSchemaCanOnlyApplyTo": If specified, the API schema generated 
          from the sdrNode can only be validly applied to this set of schemas.
        - "providesUsdShadeConnectableAPIBehavior": Used to enable a 
          connectability behavior for an API schema.
        - "isUsdShadeContainer": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Marks the
          connectable prim as a UsdShade container type.
        - "requiresUsdShadeEncapsulation": Only used when
          providesUsdShadeConnectableAPIBehavior is set to true. Configures the
          UsdShade encapsulation rules governing its connectableBehavior.
        - "tfTypeNameSuffix": Class name which will get registered with TfType 
          system. This gets appended to the domain name to register with TfType.

    Property Level Metadata:
        - USD_VARIABILITY: Property level metadata which specifies a specific 
          sdrNodeProperty should have its USD variability set to Uniform or 
          Varying
        - USD_SUPPRESS_PROPERTY: A property level metadata which determines if 
          the property should be suppressed from translation from args to 
          property spec.

    Sdr Property Metadata to SdfPropertySpec Translations
        - A "null" value for Widget sdrProperty metadata translates to 
          SdfPropertySpec Hidden metadata.
        - SdrProperty's Help metadata (Label metadata if Help metadata not 
          provided) translates to SdfPropertySpec's Documentation string 
          metadata.
        - SdrProperty's Page metadata translates to SdfPropertySpec's
          DisplayGroup metadata.
        - SdrProperty's Label metadata translates to SdfPropertySpec's
          DisplayName metadata.
        - SdrProperty's Options translates to SdfPropertySpec's AllowedTokens.
        - SdrProperty's Default value translates to SdfPropertySpec's Default
          value.
        - Connectable input properties translates to InterfaceOnly
          SdfPropertySpec's CONNECTABILITY.
    """

    import distutils.util
    import os

    # Early exit on invalid parameters
    if not schemaLayer:
        Tf.Warn("No Schema Layer provided")
        return
    if not sdrNode:
        Tf.Warn("No valid sdrNode provided")
        return

    sdrNodeMetadata = sdrNode.GetMetadata()

    if SchemaDefiningKeys.SCHEMA_NAME not in sdrNodeMetadata:
        Tf.Warn("Sdr Node (%s) does not define a schema name metadata." \
                %(sdrNode.GetName()))
        return
    schemaName = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_NAME]
    if not Tf.IsValidIdentifier(schemaName):
        Tf.RaiseRuntimeError(
            "schemaName (%s) is an invalid identifier; "
            "Provide a valid USD identifer for schemaName, example (%s) " %
            (schemaName, Tf.MakeValidIdentifier(schemaName)))

    tfTypeNameSuffix = None
    if SchemaDefiningKeys.TF_TYPENAME_SUFFIX in sdrNodeMetadata:
        tfTypeNameSuffix = sdrNodeMetadata[
            SchemaDefiningKeys.TF_TYPENAME_SUFFIX]
        if not Tf.IsValidIdentifier(tfTypeNameSuffix):
            Tf.RaiseRuntimeError("tfTypeNameSuffix (%s) is an invalid " \
                    "identifier" %(tfTypeNameSuffix))

    if SchemaDefiningKeys.SCHEMA_KIND not in sdrNodeMetadata:
        schemaKind = SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaKind = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_KIND]

    # Note: We are not working on dynamic multiple apply schemas right now.
    isAPI = schemaKind == SchemaDefiningMiscConstants.SINGLE_APPLY_SCHEMA
    # Fix schemaName and warn if needed
    if isAPI and \
        not schemaName.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created is "
                "an API schema, fixing schemaName to reflect that")
        schemaName = schemaName + SchemaDefiningMiscConstants.API_STRING

    if isAPI and tfTypeNameSuffix and \
        not tfTypeNameSuffix.endswith(SchemaDefiningMiscConstants.API_STRING):
        Tf.Warn("node metadata implies the generated schema being created "
                "is an API schema, fixing tfTypeNameSuffix to reflect that")
        tfTypeNameSuffix = tfTypeNameSuffix + \
                SchemaDefiningMiscConstants.API_STRING

    if SchemaDefiningKeys.SCHEMA_BASE not in sdrNodeMetadata:
        Tf.Warn("No schemaBase specified in node metadata, defaulting to "
                "APISchemaBase for API schemas else Typed")
        schemaBase = SchemaDefiningMiscConstants.API_SCHEMA_BASE if isAPI \
                else SchemaDefiningMiscConstants.TYPED_SCHEMA
    else:
        schemaBase = sdrNodeMetadata[SchemaDefiningKeys.SCHEMA_BASE]

    apiSchemaAutoApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO in sdrNodeMetadata:
        apiSchemaAutoApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_AUTO_APPLY_TO] \
                .split('|')

    apiSchemaCanOnlyApplyTo = None
    if SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO in sdrNodeMetadata:
        apiSchemaCanOnlyApplyTo = \
            sdrNodeMetadata[SchemaDefiningKeys.API_SCHEMA_CAN_ONLY_APPLY_TO] \
                .split('|')

    providesUsdShadeConnectableAPIBehavior = False
    if SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR in \
            sdrNodeMetadata:
        providesUsdShadeConnectableAPIBehavior = \
            distutils.util.strtobool(sdrNodeMetadata[SchemaDefiningKeys. \
                PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR])

    usdSchemaClass = None
    if isAPI and SchemaDefiningKeys.USD_SCHEMA_CLASS in sdrNodeMetadata:
        usdSchemaClass = \
            sdrNodeMetadata[SchemaDefiningKeys.USD_SCHEMA_CLASS]

    primSpec = schemaLayer.GetPrimAtPath(schemaName)

    if (primSpec):
        # if primSpec already exist, remove entirely and recreate using the
        # parsed sdr node
        if primSpec.nameParent:
            del primSpec.nameParent.nameChildren[primSpec.name]
        else:
            del primSpec.nameRoot.nameChildren[primSpec.name]

    primSpec = Sdf.PrimSpec(schemaLayer, schemaName, Sdf.SpecifierClass,
                            "" if isAPI else schemaName)

    primSpec.inheritPathList.explicitItems = ["/" + schemaBase]

    primSpecCustomData = {}
    if isAPI:
        primSpecCustomData["apiSchemaType"] = schemaKind
    if tfTypeNameSuffix:
        # Defines this classname for TfType system
        # can help avoid duplicate prefix with domain and className
        # Tf type system will automatically pick schemaName as tfTypeName if
        # this is not set!
        primSpecCustomData["className"] = tfTypeNameSuffix

    if apiSchemaAutoApplyTo:
        primSpecCustomData['apiSchemaAutoApplyTo'] = \
            Vt.TokenArray(apiSchemaAutoApplyTo)
    if apiSchemaCanOnlyApplyTo:
        primSpecCustomData['apiSchemaCanOnlyApplyTo'] = \
            Vt.TokenArray(apiSchemaCanOnlyApplyTo)

    if providesUsdShadeConnectableAPIBehavior:
        extraPlugInfo = {
            SchemaDefiningKeys.PROVIDES_USD_SHADE_CONNECTABLE_API_BEHAVIOR \
                    : True
        }
        for propKey in [SchemaDefiningKeys.IS_USD_SHADE_CONTAINER, \
                SchemaDefiningKeys.REQUIRES_USD_SHADE_ENCAPSULATION]:
            if propKey in sdrNodeMetadata:
                # Since we want to assign the types for these to bool and
                # because in python boolean type is a subset of int, we need to
                # do following instead of assign the propValue directly.
                propValue = distutils.util.strtobool(sdrNodeMetadata[propKey])
                extraPlugInfo[propKey] = bool(propValue)

        primSpecCustomData['extraPlugInfo'] = extraPlugInfo

    primSpec.customData = primSpecCustomData

    doc = sdrNode.GetHelp()
    if doc != "":
        primSpec.documentation = doc

    # gather properties from node directly generated from USD (sourceType: USD)
    # Use the usdSchemaClass tag when the generated schema being defined is an
    # API schema
    usdSchemaNode = None
    if usdSchemaClass:
        reg = Sdr.Registry()
        if usdSchemaClass.endswith(SchemaDefiningMiscConstants.API_STRING):
            # This usd schema is an API schema, we need to extract the shader
            # identifier from its primDef's shaderId field.
            primDef = Usd.SchemaRegistry().FindAppliedAPIPrimDefinition(
                usdSchemaClass)
            if primDef:
                # We are dealing with USD source type here, hence no render
                # context is required but we can still borrow node context
                # information from the sdrNode in question, since the usd source
                # type node should also belong to the same context.
                shaderIdAttrName = Sdf.Path.JoinIdentifier( \
                        sdrNode.GetContext(), PropertyDefiningKeys.SHADER_ID)
                sdrIdentifier = primDef.GetAttributeFallbackValue(
                    shaderIdAttrName)
                if sdrIdentifier != "":
                    usdSchemaNode = reg.GetNodeByIdentifierAndType(
                        sdrIdentifier,
                        SchemaDefiningMiscConstants.USD_SOURCE_TYPE)
                else:
                    Tf.Warn("No sourceId authored for '%s'." %
                            (usdSchemaClass))
            else:
                Tf.Warn("Illegal API schema provided for the usdSchemaClass "
                        "metadata. No prim definition registered for '%s'" %
                        (usdSchemaClass))

        else:
            usdSchemaNode = reg.GetNodeByIdentifierAndType(
                usdSchemaClass, SchemaDefiningMiscConstants.USD_SOURCE_TYPE)

    # Create attrSpecs from input parameters
    for propName in sdrNode.GetInputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetInput(propName),
                                         usdSchemaNode)

    # Create attrSpecs from output parameters
    for propName in sdrNode.GetOutputNames():
        _CreateAttrSpecFromNodeAttribute(primSpec, sdrNode.GetOutput(propName),
                                         usdSchemaNode, False)

    # Create token shaderId attrSpec
    shaderIdAttrName = Sdf.Path.JoinIdentifier( \
            [renderContext, sdrNode.GetContext(), PropertyDefiningKeys.SHADER_ID])
    shaderIdAttrSpec = Sdf.AttributeSpec(primSpec, shaderIdAttrName,
                                         Sdf.ValueTypeNames.Token,
                                         Sdf.VariabilityUniform)

    # Since users shouldn't need to be aware of shaderId attribute, we put this
    # in "Internal" displayGroup.
    shaderIdAttrSpec.displayGroup = PropertyDefiningKeys.INTERNAL_DISPLAY_GROUP

    # Use the identifier if explicitly provided, (it could be a shader node
    # queried using an explicit path), else use sdrNode's registered identifier.
    nodeIdentifier = overrideIdentifier if overrideIdentifier else \
            sdrNode.GetIdentifier()
    shaderIdAttrSpec.default = nodeIdentifier

    # Extra attrSpec
    schemaBasePrimDefinition = \
        Usd.SchemaRegistry().FindConcretePrimDefinition(schemaBase)
    if schemaBasePrimDefinition and \
        SchemaDefiningMiscConstants.NodeDefAPI in \
        schemaBasePrimDefinition.GetAppliedAPISchemas():
        infoIdAttrSpec = Sdf.AttributeSpec(primSpec, \
                UsdShade.Tokens.infoId, Sdf.ValueTypeNames.Token, \
                Sdf.VariabilityUniform)
        infoIdAttrSpec.default = nodeIdentifier

    schemaLayer.Save()
示例#21
0
def sync(obj_prim,
         obj: bpy.types.Object,
         mesh: bpy.types.Mesh = None,
         **kwargs):
    """ Creates pyrpr.Shape from obj.data:bpy.types.Mesh """
    from .object import sdf_name

    if not mesh:
        mesh = obj.data

    log("sync", mesh, obj)

    data = MeshData.init_from_mesh(mesh, obj=obj)
    if not data:
        return

    stage = obj_prim.GetStage()
    parent_prim = None
    parent_object = None

    if obj.parent is not None and obj_prim.GetName() != sdf_name(obj.original):
        parent_object = obj.original
        parent_prim = stage.GetPrimAtPath(f"/{sdf_name(obj.original)}")

    if parent_prim is not None and not parent_prim.IsValid():
        xform = UsdGeom.Xform.Define(stage, f"/{sdf_name(obj.original)}")
        parent_prim = xform.GetPrim()
        xform.MakeMatrixXform().Set(
            Gf.Matrix4d(parent_object.matrix_world.transposed()))
        sync(parent_prim, parent_object)

    if parent_prim is not None and parent_prim.IsValid(
    ) and parent_prim.GetChildren():
        for child in parent_prim.GetChildren():
            if child.GetTypeName() == 'Mesh':
                usd_mesh = UsdGeom.Mesh.Define(
                    stage,
                    obj_prim.GetPath().AppendChild(sdf_name(obj)))
                usd_mesh.GetPrim().GetReferences().AddInternalReference(
                    child.GetPath())

            if child.GetTypeName() == 'Material':
                usd_mesh = UsdGeom.Mesh.Get(
                    stage,
                    obj_prim.GetPath().AppendChild(sdf_name(obj)))
                usd_material = UsdShade.Material.Get(stage, child.GetPath())
                UsdShade.MaterialBindingAPI(usd_mesh).Bind(usd_material)

        return

    original_prim = stage.GetPrimAtPath(f"/{sdf_name(obj.original)}")
    if original_prim and original_prim.IsValid():
        for child in original_prim.GetChildren():
            if len(child.GetAuthoredPropertyNames()) > 0:
                return

    usd_mesh = UsdGeom.Mesh.Define(
        stage,
        obj_prim.GetPath().AppendChild(Tf.MakeValidIdentifier(mesh.name)))

    usd_mesh.CreateDoubleSidedAttr(True)
    usd_mesh.CreatePointsAttr(data.vertices)
    usd_mesh.CreateFaceVertexIndicesAttr(data.vertex_indices)
    usd_mesh.CreateFaceVertexCountsAttr(data.num_face_vertices)

    usd_mesh.CreateSubdivisionSchemeAttr(UsdGeom.Tokens.none)
    usd_mesh.CreateNormalsAttr(data.normals)
    usd_mesh.SetNormalsInterpolation(UsdGeom.Tokens.faceVarying)

    for name, uv_layer in data.uv_layers.items():
        uv_primvar = usd_mesh.CreatePrimvar(
            "st",  # default name, later we'll use sdf_path(name)
            Sdf.ValueTypeNames.TexCoord2fArray,
            UsdGeom.Tokens.faceVarying)
        uv_primvar.Set(uv_layer[0])
        uv_primvar.SetIndices(Vt.IntArray.FromNumpy(uv_layer[1]))

        break  # currently we use only first UV layer

    _assign_materials(obj_prim, obj.original, usd_mesh)
def sdf_name(obj: bpy.types.Object):
    return Tf.MakeValidIdentifier(obj.name_full)
 def sdf_name(self):
     name = Tf.MakeValidIdentifier(self.object.name_full)
     return name if self.instance_id == 0 else f"{name}_{self.instance_id}"
def sync(obj_prim, obj: bpy.types.Object, **kwargs):
    """ Creates pyrpr.Light from obj.data: bpy.types.Light """
    light = obj.data
    stage = obj_prim.GetStage()
    context = bpy.context
    is_preview_render = kwargs.get('is_preview_render', False)
    log("sync", light, obj)

    light_path = obj_prim.GetPath().AppendChild(
        Tf.MakeValidIdentifier(light.name))

    if light.type == 'POINT':
        usd_light = UsdLux.SphereLight.Define(stage, light_path)

        size = light.shadow_soft_size
        usd_light.CreateRadiusAttr(size)

    elif light.type in (
            'SUN', 'HEMI'):  # just in case old scenes will have outdated Hemi
        usd_light = UsdLux.DistantLight.Define(stage, light_path)
        angle = math.degrees(light.angle)
        usd_light.CreateAngleAttr(angle)
        intensity_attr = usd_light.CreateIntensityAttr()

        usd_utils.add_delegate_variants(
            obj_prim,
            {
                'GL': lambda: intensity_attr.
                Set(light.energy * 1736000000
                    ),  # coefficient approximated to follow RPR results
                'RPR': lambda: intensity_attr.Set(light.energy)
            })

    elif light.type == 'SPOT':
        usd_light = UsdLux.SphereLight.Define(stage, light_path)
        usd_prim = stage.GetPrimAtPath(light_path)

        usd_light.CreateTreatAsPointAttr(1)

        spot_size = math.degrees(light.spot_size)

        usd_shaping = UsdLux.ShapingAPI(usd_prim)
        usd_shaping.CreateShapingConeAngleAttr(spot_size / 2)
        usd_shaping.CreateShapingConeSoftnessAttr(light.spot_blend)

        usd_shaping.Apply(usd_prim)

    elif light.type == 'AREA':
        shape_type = light.shape

        if shape_type == 'SQUARE':
            usd_light = UsdLux.RectLight.Define(stage, light_path)
            usd_light.CreateWidthAttr(light.size)
            usd_light.CreateHeightAttr(light.size)

        elif shape_type == 'RECTANGLE':
            usd_light = UsdLux.RectLight.Define(stage, light_path)
            usd_light.CreateWidthAttr(light.size)
            usd_light.CreateHeightAttr(light.size_y)

        elif shape_type == 'DISK':
            usd_light = UsdLux.DiskLight.Define(stage, light_path)
            usd_light.CreateRadiusAttr(light.size /
                                       2)  # light.size is diameter

        else:  # shape_type == 'ELLIPSE':
            usd_light = UsdLux.DiskLight.Define(stage, light_path)
            usd_light.CreateRadiusAttr((light.size + light.size_y) /
                                       4)  # average of light.size is diameter

    else:
        raise ValueError("Unsupported light type", light, light.type)

    power = get_radiant_power(light)

    color_attr = usd_light.CreateColorAttr()

    if is_preview_render:
        # Material Previews are overly bright, that's why
        # decreasing light intensity for material preview by 10 times
        power *= 0.1

    color_attr.Set(tuple(power))