Beispiel #1
0
static 
bool _GetMayaDictValue(const UsdAttribute& attr, const TfToken& key, T* outVal)
{
    VtValue data = attr.GetCustomDataByKey(_tokens->Maya);
    if (!data.IsEmpty()) {
        if (data.IsHolding<VtDictionary>()) {
            VtValue val;
            if (TfMapLookup(data.UncheckedGet<VtDictionary>(), key, &val)) {
                if (val.IsHolding<T>()) {
                    *outVal = val.UncheckedGet<T>();
                    return true;
                }
                else {
                    TF_WARN("Unexpected type for %s[%s] on <%s>.",
                            _tokens->Maya.GetText(),
                            key.GetText(),
                            attr.GetPath().GetText());
                }
            }
        }
        else {
            TF_WARN("Expected to get %s on <%s> to be a dictionary.",
                    _tokens->Maya.GetText(),
                    attr.GetPath().GetText());
        }
    }
    return false;
}
Beispiel #2
0
static bool
_GetMetadataUnchecked(
    const MFnDependencyNode& node,
    const TfToken& key,
    VtValue* value)
{
    VtValue fallback = SdfSchema::GetInstance().GetFallback(key);
    if (fallback.IsEmpty()) {
        return false;
    }

    std::string mayaAttrName = _GetMayaAttrNameForMetadataKey(key);
    MPlug plug = node.findPlug(mayaAttrName.c_str());
    if (plug.isNull()) {
        return false;
    }

    TfType ty = fallback.GetType();
    VtValue result = UsdMayaWriteUtil::GetVtValue(plug, ty, TfToken());
    if (result.IsEmpty()) {
        TF_RUNTIME_ERROR(
                "Cannot convert plug '%s' into metadata '%s' (%s)",
                plug.name().asChar(),
                key.GetText(),
                ty.GetTypeName().c_str());
        return false;
    }

    *value = result;
    return true;
}
Beispiel #3
0
UsdAttribute
UsdSchemaBase::_CreateAttr(TfToken const &attrName,
                           SdfValueTypeName const & typeName,
                           bool custom, SdfVariability variability,
                           VtValue const &defaultValue, 
                           bool writeSparsely) const
{
    UsdPrim prim(GetPrim());
    
    if (writeSparsely && !custom){
        // We are a builtin, and we're trying to be parsimonious.
        // We only need to even CREATE a propertySpec if we are
        // authoring a non-fallback default value
        UsdAttribute attr = prim.GetAttribute(attrName);
        VtValue  fallback;
        if (defaultValue.IsEmpty() ||
            (!attr.HasAuthoredValueOpinion()
             && attr.Get(&fallback)
             && fallback == defaultValue)){
            return attr;
        }
    }
    
    UsdAttribute attr(prim.CreateAttribute(attrName, typeName,
                                           custom, variability));
    if (attr && !defaultValue.IsEmpty()) {
        attr.Set(defaultValue);
    }

    return attr;
}
Beispiel #4
0
static void
_ProcessChildren(
    const TfToken& childrenField, 
    const VtValue& srcChildrenValue, const VtValue& dstChildrenValue,
    const SdfLayerHandle& srcLayer, const SdfPath& srcPath, bool childrenInSrc,
    const SdfLayerHandle& dstLayer, const SdfPath& dstPath, bool childrenInDst,
    _CopyStack* copyStack)
{
    typedef typename ChildPolicy::FieldType FieldType;
    typedef std::vector<FieldType> ChildrenVector;

    if (!TF_VERIFY(srcChildrenValue.IsHolding<ChildrenVector>() || 
                   srcChildrenValue.IsEmpty()) ||
        !TF_VERIFY(dstChildrenValue.IsHolding<ChildrenVector>() || 
                   dstChildrenValue.IsEmpty())) {
        return;
    }

    const ChildrenVector emptyChildren;
    const ChildrenVector& srcChildren = srcChildrenValue.IsEmpty() ? 
        emptyChildren : srcChildrenValue.UncheckedGet<ChildrenVector>();
    const ChildrenVector& dstChildren = dstChildrenValue.IsEmpty() ? 
        emptyChildren : dstChildrenValue.UncheckedGet<ChildrenVector>();

    for (size_t i = 0; i < srcChildren.size(); ++i) {
        if (srcChildren[i].IsEmpty() || dstChildren[i].IsEmpty()) {
            continue;
        }

        const SdfPath srcChildPath = 
            ChildPolicy::GetChildPath(srcPath, srcChildren[i]);
        const SdfPath dstChildPath = 
            ChildPolicy::GetChildPath(dstPath, dstChildren[i]);

        copyStack->emplace_back(srcChildPath, dstChildPath);
    }

    // Add entries to the copy stack to mark the removal of child specs
    // in the destination layer that aren't included in the list of children
    // to copy.
    if (childrenInDst) {
        const VtValue oldDstChildrenValue = 
            dstLayer->GetField(dstPath, childrenField);
        if (!TF_VERIFY(oldDstChildrenValue.IsHolding<ChildrenVector>())) {
            return;
        }

        for (const auto& oldDstChild : 
                 oldDstChildrenValue.UncheckedGet<ChildrenVector>()) {
            if (std::find(dstChildren.begin(), dstChildren.end(), 
                    oldDstChild) == dstChildren.end()) {
                
                const SdfPath oldDstChildPath = 
                    ChildPolicy::GetChildPath(dstPath, oldDstChild);
                copyStack->emplace_back(SdfPath(), oldDstChildPath);
            }
        }
    }
}
Beispiel #5
0
void
HdPoints::_PopulateVertexPrimVars(HdDrawItem *drawItem,
                                  HdChangeTracker::DirtyBits *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HD_MALLOC_TAG_FUNCTION();

    SdfPath const& id = GetId();
    HdSceneDelegate* delegate = GetDelegate();
    HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance();

    // The "points" attribute is expected to be in this list.
    TfTokenVector primVarNames = delegate->GetPrimVarVertexNames(id);
    TfTokenVector const& vars = delegate->GetPrimVarVaryingNames(id);
    primVarNames.insert(primVarNames.end(), vars.begin(), vars.end());

    HdBufferSourceVector sources;
    sources.reserve(primVarNames.size());

    int pointsIndexInSourceArray = -1;

    TF_FOR_ALL(nameIt, primVarNames) {
        if (not HdChangeTracker::IsPrimVarDirty(*dirtyBits, id, *nameIt))
            continue;

        // TODO: We don't need to pull primvar metadata every time a value
        // changes, but we need support from the delegate.

        //assert name not in range.bufferArray.GetResources()
        VtValue value = delegate->Get(id, *nameIt);

        if (!value.IsEmpty()) {
            // Store where the points will be stored in the source array
            // we need this later to figure out if the number of points is changing
            // and we need to force a garbage collection to resize the buffer
            if (*nameIt == HdTokens->points) {
                pointsIndexInSourceArray = sources.size();
            }

            // XXX: do we need special treatment for width as basicCurves?

            HdBufferSourceSharedPtr source(new HdVtBufferSource(*nameIt, value));
            sources.push_back(source);
        }
    }

    // return before allocation if it's empty.
    if (sources.empty())
        return;

    if (not drawItem->GetVertexPrimVarRange() or
            not drawItem->GetVertexPrimVarRange()->IsValid()) {
        // initialize buffer array
        HdBufferSpecVector bufferSpecs;
        TF_FOR_ALL(it, sources) {
            (*it)->AddBufferSpecs(&bufferSpecs);
        }
Beispiel #6
0
bool 
UsdGeomPrimvar::ComputeFlattened(VtValue *value, UsdTimeCode time) const
{
    VtValue attrVal;
    if (!Get(&attrVal, time)) {
        return false;
    }

    // If the primvar attr value is not an array or if the primvar isn't 
    // indexed, simply return the attribute value.
    if (!attrVal.IsArrayValued() || !IsIndexed()) {
        *value = VtValue::Take(attrVal);
        return true;
    }

    VtIntArray indices;
    if (!GetIndices(&indices, time)) {
        TF_CODING_ERROR("No indices authored for indexed primvar <%s>.", 
                        _attr.GetPath().GetText());
        return false;
    }

    // Handle all known supported array value types.
    bool foundSupportedType =
        _ComputeFlattenedArray<VtVec2fArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec2dArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec2iArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec2hArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec3fArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec3dArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec3iArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec3hArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec4fArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec4dArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec4iArray>(attrVal, indices, value)       || 
        _ComputeFlattenedArray<VtVec4hArray>(attrVal, indices, value)       ||
        _ComputeFlattenedArray<VtMatrix3dArray>(attrVal, indices, value)    || 
        _ComputeFlattenedArray<VtMatrix4dArray>(attrVal, indices, value)    ||
        _ComputeFlattenedArray<VtStringArray>(attrVal, indices, value)      ||
        _ComputeFlattenedArray<VtDoubleArray>(attrVal, indices, value)      ||
        _ComputeFlattenedArray<VtIntArray>(attrVal, indices, value)         ||
        _ComputeFlattenedArray<VtFloatArray>(attrVal, indices, value)       ||
        _ComputeFlattenedArray<VtHalfArray>(attrVal, indices, value);

    if (!foundSupportedType) {
        TF_WARN("Unsupported indexed primvar value type %s.", 
                attrVal.GetTypeName().c_str());
    }

    return !value->IsEmpty();
}
Beispiel #7
0
bool
UsdMayaAdaptor::AttributeAdaptor::Get(VtValue* value) const
{
    if (!*this) {
        return false;
    }

    VtValue result = UsdMayaWriteUtil::GetVtValue(_plug,
            _attrDef->GetTypeName());
    if (result.IsEmpty()) {
        return false;
    }

    *value = result;
    return true;
}
Beispiel #8
0
void
Hd_VtExtractor::Extract(const VtValue &value)
{
    // Type dispatch to _Extractor.
    //
    // Iterate over each acceptable type T, calling typeChecker<T>(), which
    // internally calls value.IsHolding<T>(); if the VtValue IS holding a T,
    // then pass the held value to _Extractor::Extract<T>(value).
    _Extractor e;

    boost::mpl::for_each<_AcceptedTypes>(_TypeChecker<_Extractor>(value, e));

    // Guarantee that the _Extractor::Extract method was called exactly once
    // and issue a runtime error otherwise. (The only case where Extract wont
    // be called is when the VtValue is holding an unacceptable type).
    if (e.GetNumComponents() == 0) {
        TF_RUNTIME_ERROR("Trying to extract a VtValue holding "
                         "unacceptable type: %s",
                         value.GetType().GetTypeName().c_str());
        return;
    }

    const _GLDataType &glDataType  = e.GetGLDataType();

    _glComponentType = glDataType.componentType;
    _glElementType   = glDataType.elementType;
    _size            = e.GetSize();
    _numComponents   = e.GetNumComponents();
    _data            = e.GetData();
}
PXR_NAMESPACE_OPEN_SCOPE


static
void
_ClearBuffer(GLenum buffer, GLint drawBuffer, const VtValue &value)
{
    // XXX: There has to be a better way to handle the different formats.
    if (value.IsHolding<int>()) {
        glClearBufferiv(buffer, drawBuffer, &value.UncheckedGet<int>());
    } else if (value.IsHolding<GfVec2i>()) {
        glClearBufferiv(buffer, drawBuffer, value.UncheckedGet<GfVec2i>().GetArray());
    } else if (value.IsHolding<GfVec3i>()) {
        glClearBufferiv(buffer, drawBuffer, value.UncheckedGet<GfVec3i>().GetArray());
    } else if (value.IsHolding<GfVec4i>()) {
        glClearBufferiv(buffer, drawBuffer, value.UncheckedGet<GfVec4i>().GetArray());
    } else if (value.IsHolding<float>()) {
        glClearBufferfv(buffer, drawBuffer, &value.UncheckedGet<float>());
    } else if (value.IsHolding<GfVec2f>()) {
        glClearBufferfv(buffer, drawBuffer, value.UncheckedGet<GfVec2f>().GetArray());
    } else if (value.IsHolding<GfVec3f>()) {
        glClearBufferfv(buffer, drawBuffer, value.UncheckedGet<GfVec3f>().GetArray());
    } else if (value.IsHolding<GfVec4f>()) {
        glClearBufferfv(buffer, drawBuffer, value.UncheckedGet<GfVec4f>().GetArray());
    } else {
      TF_CODING_ERROR("Unsupported clear value type: %s",
                      value.GetTypeName().c_str());
    }
}
Beispiel #10
0
bool
SdfPropertySpec::SetDefaultValue(const VtValue &defaultValue)
{
    if (defaultValue.IsEmpty()) {
        ClearDefaultValue();
        return true;
    }

    if (defaultValue.IsHolding<SdfValueBlock>()) {
        return SetField(SdfFieldKeys->Default, defaultValue);
    }

    TfType valueType = GetValueType();
    if (valueType.IsUnknown()) {
        TF_CODING_ERROR("Can't set value on attribute <%s> with "
                        "unknown type \"%s\"",
                        GetPath().GetText(),
                        GetTypeName().GetAsToken().GetText());
        return false;
    }

    if (ARCH_UNLIKELY(valueType.GetTypeid() == typeid(void))) {
        // valueType may be provided by a plugin that has not been loaded.
        // In that case, we cannot get the type info, which is required to cast.
        // So we load the plugin in that case.
        if (PlugPluginPtr p = 
                PlugRegistry::GetInstance().GetPluginForType(valueType)) {
            p->Load();
        }
    }

    VtValue value = VtValue::CastToTypeid(defaultValue, valueType.GetTypeid());
    if (value.IsEmpty()) {
        TF_CODING_ERROR("Can't set value on <%s> to %s: "
                        "expected a value of type \"%s\"",
                        GetPath().GetText(),
                        TfStringify(defaultValue).c_str(),
                        valueType.GetTypeName().c_str());
        return false;
    }
    return SetField(SdfFieldKeys->Default, value);
}
Beispiel #11
0
static 
void _SetMayaDictValue(const UsdAttribute& attr, const TfToken& flagName, const T& val)
{
    VtValue data = attr.GetCustomDataByKey(_tokens->Maya);

    VtDictionary newDict;
    if (!data.IsEmpty()) {
        if (data.IsHolding<VtDictionary>()) {
            newDict = data.UncheckedGet<VtDictionary>();
        }
        else {
            TF_WARN("Expected to get %s on <%s> to be a dictionary.",
                    _tokens->Maya.GetText(),
                    attr.GetPath().GetText());
            return;
        }
    }
    newDict[flagName] = VtValue(val);
    attr.SetCustomDataByKey(_tokens->Maya, VtValue(newDict));
}
Beispiel #12
0
bool
UsdMayaAdaptor::SetMetadata(
    const TfToken& key,
    const VtValue& value,
    MDGModifier& modifier)
{
    if (!*this) {
        TF_CODING_ERROR("Adaptor is not valid");
        return false;
    }

    VtValue fallback;
    if (!SdfSchema::GetInstance().IsRegistered(key, &fallback)) {
        TF_CODING_ERROR("Metadata key '%s' is not registered", key.GetText());
        return false;
    }

    if (fallback.IsEmpty()) {
        return false;
    }

    VtValue castValue = VtValue::CastToTypeOf(value, fallback);
    if (castValue.IsEmpty()) {
        TF_CODING_ERROR("Can't cast value to type '%s'",
                fallback.GetTypeName().c_str());
        return false;
    }

    std::string mayaAttrName = _GetMayaAttrNameForMetadataKey(key);
    std::string mayaNiceAttrName = key.GetText();
    MFnDependencyNode node(_handle.object());
    TfType ty = fallback.GetType();
    MObject attrObj = UsdMayaReadUtil::FindOrCreateMayaAttr(
            ty, TfToken(), SdfVariabilityUniform,
            node, mayaAttrName, mayaNiceAttrName, modifier);
    if (attrObj.isNull()) {
        return false;
    }

    MPlug plug = node.findPlug(attrObj);
    if (!UsdMayaReadUtil::SetMayaAttr(plug, castValue, modifier)) {
        return false;
    }

    return true;
}
Beispiel #13
0
GlfGLSLFXConfig::Parameters
GlfGLSLFXConfig::_GetParameters(VtDictionary const & dict, 
                                 string *errorStr) const
{
    Parameters ret;

    VtValue params;

    // look for the params section
    if (!TfMapLookup(dict, _tokens->parameters, &params)) {
        return ret;
    }

    // verify that it holds a VtDictionary
    if (!params.IsHolding<VtDictionary>()) {
        *errorStr = TfStringPrintf("%s declaration expects a dictionary value",
                                   _tokens->parameters.GetText());
        return ret;
    }

    // look for the parameterOrder section: 
    vector<string> paramOrder;
    VtValue paramOrderAny;
    TfMapLookup(dict, _tokens->parameterOrder, &paramOrderAny);

    if (!paramOrderAny.IsEmpty()) {
        // verify the type
        if (!paramOrderAny.IsHolding<vector<VtValue> >()) {
            *errorStr =
                TfStringPrintf("%s declaration expects a list of strings",
                               _tokens->parameterOrder.GetText());
            return ret;
        }

        const vector<VtValue>& paramOrderList =
            paramOrderAny.UncheckedGet<vector<VtValue> >();
        TF_FOR_ALL(paramIt, paramOrderList) {
            const VtValue& val = *paramIt;
            // verify that this value is a string
            if (!val.IsHolding<string>()) {
                *errorStr = TfStringPrintf("%s declaration expects a list of "
                                           "strings",
                                           _tokens->parameterOrder.GetText());
                return ret;
            }

            const string& paramName = val.UncheckedGet<string>();
            if (std::find(paramOrder.begin(), paramOrder.end(), paramName) ==
                    paramOrder.end()) {
                paramOrder.push_back(paramName);
            }
        }
    }


    const VtDictionary& paramsDict = params.UncheckedGet<VtDictionary>();
    // pre-process the paramsDict in order to get the merged ordering
    TF_FOR_ALL(it, paramsDict) {
        string paramName = it->first;
        if (std::find(paramOrder.begin(), paramOrder.end(), paramName) ==
                paramOrder.end()) {
            paramOrder.push_back(paramName);
        }
    }
Beispiel #14
0
void
HdRprim::_PopulateConstantPrimVars(HdSceneDelegate* delegate,
                                   HdDrawItem *drawItem,
                                   HdDirtyBits *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    SdfPath const& id = GetId();
    HdRenderIndex &renderIndex = delegate->GetRenderIndex();
    HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance();


    // XXX: this should be in a different method
    // XXX: This should be in HdSt getting the HdSt Shader
    const HdShader *shader = static_cast<const HdShader *>(
                                  renderIndex.GetSprim(HdPrimTypeTokens->shader,
                                                       _surfaceShaderID));

    if (shader == nullptr) {
        shader = static_cast<const HdShader *>(
                        renderIndex.GetFallbackSprim(HdPrimTypeTokens->shader));
    }

    _sharedData.surfaceShader = shader->GetShaderCode();


    // update uniforms
    HdBufferSourceVector sources;
    if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) {
        GfMatrix4d transform = delegate->GetTransform(id);
        _sharedData.bounds.SetMatrix(transform); // for CPU frustum culling

        HdBufferSourceSharedPtr source(new HdVtBufferSource(
                                           HdTokens->transform,
                                           transform));
        sources.push_back(source);
        source.reset(new HdVtBufferSource(HdTokens->transformInverse,
                                          transform.GetInverse()));
        sources.push_back(source);

        // if this is a prototype (has instancer),
        // also push the instancer transform separately.
        if (!_instancerID.IsEmpty()) {
            // gather all instancer transforms in the instancing hierarchy
            VtMatrix4dArray rootTransforms = _GetInstancerTransforms(delegate);
            VtMatrix4dArray rootInverseTransforms(rootTransforms.size());
            bool leftHanded = transform.IsLeftHanded();
            for (size_t i = 0; i < rootTransforms.size(); ++i) {
                rootInverseTransforms[i] = rootTransforms[i].GetInverse();
                // flip the handedness if necessary
                leftHanded ^= rootTransforms[i].IsLeftHanded();
            }

            source.reset(new HdVtBufferSource(
                             HdTokens->instancerTransform,
                             rootTransforms, /*staticArray=*/true));
            sources.push_back(source);
            source.reset(new HdVtBufferSource(
                             HdTokens->instancerTransformInverse,
                             rootInverseTransforms, /*staticArray=*/true));
            sources.push_back(source);

            // XXX: It might be worth to consider to have isFlipped
            // for non-instanced prims as well. It can improve
            // the drawing performance on older-GPUs by reducing
            // fragment shader cost, although it needs more GPU memory.

            // set as int (GLSL needs 32-bit align for bool)
            source.reset(new HdVtBufferSource(
                             HdTokens->isFlipped, VtValue(int(leftHanded))));
            sources.push_back(source);
        }
    }
    if (HdChangeTracker::IsExtentDirty(*dirtyBits, id)) {
        _sharedData.bounds.SetRange(GetExtent(delegate));

        GfVec3d const & localMin = drawItem->GetBounds().GetBox().GetMin();
        HdBufferSourceSharedPtr sourceMin(new HdVtBufferSource(
                                           HdTokens->bboxLocalMin,
                                           VtValue(GfVec4f(
                                               localMin[0],
                                               localMin[1],
                                               localMin[2], 0))));
        sources.push_back(sourceMin);

        GfVec3d const & localMax = drawItem->GetBounds().GetBox().GetMax();
        HdBufferSourceSharedPtr sourceMax(new HdVtBufferSource(
                                           HdTokens->bboxLocalMax,
                                           VtValue(GfVec4f(
                                               localMax[0],
                                               localMax[1],
                                               localMax[2], 0))));
        sources.push_back(sourceMax);
    }

    if (HdChangeTracker::IsPrimIdDirty(*dirtyBits, id)) {
        GfVec4f primIdColor;
        int32_t primId = GetPrimId();
        HdBufferSourceSharedPtr source(new HdVtBufferSource(
                                           HdTokens->primID,
                                           VtValue(primId)));
        sources.push_back(source);
    }

    if (HdChangeTracker::IsAnyPrimVarDirty(*dirtyBits, id)) {
        TfTokenVector primVarNames = delegate->GetPrimVarConstantNames(id);
        sources.reserve(sources.size()+primVarNames.size());
        TF_FOR_ALL(nameIt, primVarNames) {
            if (HdChangeTracker::IsPrimVarDirty(*dirtyBits, id, *nameIt)) {
                VtValue value = delegate->Get(id, *nameIt);

                // XXX Hydra doesn't support string primvar yet
                if (value.IsHolding<std::string>()) continue;

                if (!value.IsEmpty()) {
                    HdBufferSourceSharedPtr source(
                        new HdVtBufferSource(*nameIt, value));

                    // if it's an unacceptable type, skip it (e.g. std::string)
                    if (source->GetNumComponents() > 0) {
                        sources.push_back(source);
                    }
                }
            }
        }
    }
void
HdStExtComputation::Sync(HdSceneDelegate *sceneDelegate,
                         HdRenderParam   *renderParam,
                         HdDirtyBits     *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();
    TF_DEBUG(HD_EXT_COMPUTATION_UPDATED).Msg(
        "HdStExtComputation::Sync %s\n", GetId().GetText());

    HdExtComputation::_Sync(sceneDelegate, renderParam, dirtyBits);

    // We only commit GPU resources when directly executing a GPU computation
    // or when aggregating inputs for a downstream computation.
    if (GetGpuKernelSource().empty() && !IsInputAggregation()) {
        return;
    }

    HdRenderIndex &renderIndex = sceneDelegate->GetRenderIndex();
    HdStResourceRegistrySharedPtr const & resourceRegistry =
        boost::dynamic_pointer_cast<HdStResourceRegistry>(
                              renderIndex.GetResourceRegistry());

    HdBufferSourceVector inputs;
    for (TfToken const & inputName: GetSceneInputNames()) {
        VtValue inputValue = sceneDelegate->GetExtComputationInput(
                                                GetId(), inputName);
        size_t arraySize =
            inputValue.IsArrayValued() ? inputValue.GetArraySize() : 1;
        HdBufferSourceSharedPtr inputSource = HdBufferSourceSharedPtr(
                    new HdVtBufferSource(inputName, inputValue, arraySize));
        if (inputSource->IsValid()) {
            inputs.push_back(inputSource);
        } else {
            TF_WARN("Unsupported type %s for source %s in extComputation %s.",
                    inputValue.GetType().GetTypeName().c_str(),
                    inputName.GetText(), GetId().GetText());
        }
    }

    _inputRange.reset();
    if (!inputs.empty()) {
        if (_IsEnabledSharedExtComputationData() && IsInputAggregation()) {
            uint64_t inputId = _ComputeSharedComputationInputId(0, inputs);

            HdInstance<uint64_t, HdBufferArrayRangeSharedPtr> barInstance;
            std::unique_lock<std::mutex> regLog =
                resourceRegistry->RegisterExtComputationDataRange(inputId,
                                                                  &barInstance);

            if (barInstance.IsFirstInstance()) {
                // Allocate the first buffer range for this input key
                _inputRange = _AllocateComputationDataRange(inputs,
                                                            resourceRegistry);
                barInstance.SetValue(_inputRange);

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Allocated shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            } else {
                // Share the existing buffer range for this input key
                _inputRange = barInstance.GetValue();

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Reused shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            }

        } else {
            // We're not sharing, so go ahead and allocate new buffer range.
            _inputRange = _AllocateComputationDataRange(inputs,
                                                        resourceRegistry);
        }

        // Make sure that we also release any stale input range data
        renderIndex.GetChangeTracker().SetGarbageCollectionNeeded();
    }
}
Beispiel #16
0
static void testValue() {
    {
        // Test that we can create values holding non-streamable types. 
        _NotStreamable n;
        VtValue v(n);
        VtValue copy = v;
        copy = n;
    }

    {
        // Test that we can store non-default-constructible objects in VtValue.
        _NotDefaultConstructible n(123);
        VtValue v(n);
        VtValue copy = v;
        copy = n;
    }

    {
        VtValue v(Vt_TestEnumVal1);
        TF_AXIOM(TfStringify(v) == "Vt_TestEnumVal1");
        v = Vt_TestEnumVal2;
        TF_AXIOM(TfStringify(v) == "Vt_TestEnumVal2");
    }

    {
        // Test that floating-point values stream as expected.
        TF_AXIOM(TfStringify(VtValue(0.0)) == "0");
        TF_AXIOM(TfStringify(VtValue(3.14159)) == "3.14159");
        TF_AXIOM(TfStringify(VtValue(0.1)) == "0.1");
        TF_AXIOM(TfStringify(VtValue(-0.000001)) == "-0.000001");
        TF_AXIOM(TfStringify(
             VtValue(std::numeric_limits<double>::infinity())) == "inf");
        TF_AXIOM(TfStringify(
             VtValue(-std::numeric_limits<double>::infinity())) == "-inf");

        TF_AXIOM(TfStringify(VtValue(0.0f)) == "0");
        TF_AXIOM(TfStringify(VtValue(3.14159f)) == "3.14159");
        TF_AXIOM(TfStringify(VtValue(0.1f)) == "0.1");
        TF_AXIOM(TfStringify(VtValue(-0.000001f)) == "-0.000001");
        TF_AXIOM(TfStringify(
             VtValue(std::numeric_limits<float>::infinity())) == "inf");
        TF_AXIOM(TfStringify(
             VtValue(-std::numeric_limits<float>::infinity())) == "-inf");
    }

    VtValue v(1.234);
    if (!v.IsHolding<double>())
        die("IsHolding");
    
    if (v.Get<double>() != 1.234)
        die("Get");

    if (v.GetTypeid() != typeid(double))
        die("GetTypeid");

    if (v.GetType() != TfType::Find<double>())
        die("GetType for unregistered type");

    if (v.GetElementTypeid() != typeid(void))
        die("GetElementTypeid for non-shaped type");

    v = VtValue("hello world");
    if (v.GetElementTypeid() != typeid(void))
        die("GetElementTypeid for non-shaped, non-stack-held type");

    if (v.IsArrayValued())
        die("IsArrayValued for non-array type");

    // Now test with shaped case.
    v = VtValue(VtDoubleArray(9));
    if (v.GetElementTypeid() != typeid(double))
        die("GetElementTypeid");

    // Test casts...

    v = VtValue(2.345);
    if (!v.CanCast<double>())
        die("CanCast to same type");
    if (v != VtValue::Cast<double>(v))
        die("Cast to same type");

    v = VtValue(2.345);
    if (!v.CanCast<int>())
        die("CanCast double to int");
    if (v.Cast<int>() != 2)
        die("Cast double to int");

    v = VtValue(2.345);
    if (!v.CanCast<short>())
        die("CanCast double to short");
    if (v.Cast<short>() != short(2))
        die("Cast double to short");

    v = VtValue(1.25);
    if (!v.CanCast<float>())
        die("CanCast double to float");
    if (v.Cast<float>() != 1.25f)
        die("Cast double to float");

    v = VtValue(1.25);
    if (v.CanCast<GfVec3d>())
        die("CanCast double to Vec3d");
    if (!v.Cast<GfVec3d>().IsEmpty())
        die("Cast to Vec3d type is not empty");

    v = VtValue(1.25);
    if (!v.CanCastToTypeOf(v))
        die("CanCast to same type");
    if (v.CastToTypeOf(v).Get<double>() != 1.25)
        die("Casting to same type got wrong value");
    
    v = VtValue(1.25);
    VtValue v2 = VtValue(3);
    if (!v.CanCastToTypeOf(v2))
        die("CanCast to type of another value");
    if (v2.CastToTypeOf(v).Get<double>() != 3.0)
        die("Could not cast to type of another value");

    v = VtValue(1.25);
    v2 = VtValue(3);
    if (!v.CanCastToTypeOf(v2))
        die("CanCast to type of another value");
    if (VtValue::CastToTypeOf(v2, v).Get<double>() != 3.0)
        die("Could not cast to type of another value");

    v = VtValue(1.25);
    if (!v.CanCastToTypeid(typeid(double)))
        die("CanCast to typeid of same type");
    if (!v.CanCastToTypeid(typeid(int)))
        die("CanCast double to typeid of int");
    if (v.CanCastToTypeid(typeid(GfVec3d)))
        die("CanCast double to typeid of GfVec3d");

    // Check that too large doubles cast to float infinities
    v = VtValue(1e50);
    if (!v.CanCast<float>())
        die("CanCast of too large double to float");
    if (v.Cast<float>() != std::numeric_limits<float>::infinity())
        die("Cast of too large double to float is not +inf");
    
    v = VtValue(-1e50);
    if (!v.CanCast<float>())
        die("CanCast of too small double to float");
    if (v.Cast<float>() != -std::numeric_limits<float>::infinity())
        die("Cast of too small double to float is not -inf");

    // Check that double infinities cast to float infinities
    v = VtValue(std::numeric_limits<double>::infinity());
    if (!v.CanCast<float>())
        die("CanCast of double +inf to float");
    if (v.Cast<float>() != std::numeric_limits<float>::infinity())
        die("Cast of double +inf to float is not +inf");

    v = VtValue(-std::numeric_limits<double>::infinity());
    if (!v.CanCast<float>())
        die("CanCast of double -inf to float");
    if (v.Cast<float>() != -std::numeric_limits<float>::infinity())
        die("Cast of double -inf to float is not -inf");

    // Check that float infinities cast to double infinities
    v = VtValue(std::numeric_limits<float>::infinity());
    if (!v.CanCast<double>())
        die("CanCast of float +inf to double");
    if (v.Cast<double>() != std::numeric_limits<double>::infinity())
        die("Cast of float +inf to double is not +inf");

    v = VtValue(-std::numeric_limits<float>::infinity());
    if (!v.CanCast<double>())
        die("CanCast of float -inf to double");
    if (v.Cast<double>() != -std::numeric_limits<double>::infinity())
        die("Cast of float -inf to double is not -inf");

    // Check that really large long long casts to double
    v = VtValue(1000000000000000000ll);
    if (!v.CanCast<double>())
        die("CanCast of really large long long to double");
    if (v.Cast<double>() != 1e+18)
        die("Cast of really large long long to double");

    // Check that really large long long casts to float
    v = VtValue(1000000000000000000ll);
    if (!v.CanCast<float>())
        die("CanCast of really large long long to float");
    if (v.Cast<float>() != 1e+18f)
        die("Cast of really large long long to float");
        
    // Check that really large long long casts to GfHalf infinity
    v = VtValue(1000000000000000000ll);
    if (!v.CanCast<GfHalf>())
        die("CanCast of really large long long to GfHalf");
    if (v.Cast<GfHalf>() != std::numeric_limits<GfHalf>::infinity())
        die("Cast of really large long long to GfHalf is not +inf");

    // Check that really small long long casts to minus GfHalf infinity
    v = VtValue(-1000000000000000000ll);
    if (!v.CanCast<GfHalf>())
        die("CanCast of really small long long to GfHalf");
    if (v.Cast<GfHalf>() != -std::numeric_limits<GfHalf>::infinity())
        die("Cast of really small long long to GfHalf is not -inf");

    // Check that too large unsigned short casts to GfHalf infinity
    v = VtValue((unsigned short)65535);
    if (!v.CanCast<GfHalf>())
        die("CanCast of too large unsigned short to GfHalf");
    if (v.Cast<GfHalf>() != std::numeric_limits<GfHalf>::infinity())
        die("Cast of too large unsigned short to GfHalf is not +inf");

    // Some sanity checks
    v = VtValue((int)0);
    if (!v.CanCast<double>())
        die("CanCast of integer zero to double");
    if (v.Cast<double>() != 0.0)
        die("Cast of integer zero to double not zero");

    v = VtValue((int)-1);
    if (!v.CanCast<double>())
        die("CanCast of integer -1 to double");
    if (v.Cast<double>() != -1.0)
        die("Cast of integer -1 to double not -1");

    v = VtValue((int)+1);
    if (!v.CanCast<double>())
        die("CanCast of integer one to double");
    if (v.Cast<double>() != +1.0)
        die("Cast of integer one to double not one");

    // Range-checked casts.
    v = VtValue(std::numeric_limits<short>::max());
    v.Cast<short>();
    TF_AXIOM(v.IsHolding<short>() &&
             v.UncheckedGet<short>() == std::numeric_limits<short>::max());
    // Out-of-range should fail.
    v = VtValue(std::numeric_limits<int>::max());
    v.Cast<short>();
    TF_AXIOM(v.IsEmpty());

    v = VtValue(std::numeric_limits<unsigned int>::max());
    v.Cast<int>();
    TF_AXIOM(v.IsEmpty());

    // expected to succeed
    _TestVecCast<GfVec2h>(GfVec2i(1, 2));
    _TestVecCast<GfVec2f>(GfVec2i(1, 2));
    _TestVecCast<GfVec2d>(GfVec2i(1, 2));
    _TestVecCast<GfVec2f>(GfVec2h(1, 2));
    _TestVecCast<GfVec2d>(GfVec2h(1, 2));
    _TestVecCast<GfVec2d>(GfVec2f(1, 2));
    _TestVecCast<GfVec2h>(GfVec2f(1, 2));
    _TestVecCast<GfVec2h>(GfVec2d(1, 2));
    _TestVecCast<GfVec2f>(GfVec2d(1, 2));

    _TestVecCast<GfVec3h>(GfVec3i(1, 2, 3));
    _TestVecCast<GfVec3f>(GfVec3i(1, 2, 3));
    _TestVecCast<GfVec3d>(GfVec3i(1, 2, 3));
    _TestVecCast<GfVec3f>(GfVec3h(1, 2, 3));
    _TestVecCast<GfVec3d>(GfVec3h(1, 2, 3));
    _TestVecCast<GfVec3d>(GfVec3f(1, 2, 3));
    _TestVecCast<GfVec3h>(GfVec3f(1, 2, 3));
    _TestVecCast<GfVec3h>(GfVec3d(1, 2, 3));
    _TestVecCast<GfVec3f>(GfVec3d(1, 2, 3));

    _TestVecCast<GfVec4h>(GfVec4i(1, 2, 3, 4));
    _TestVecCast<GfVec4f>(GfVec4i(1, 2, 3, 4));
    _TestVecCast<GfVec4d>(GfVec4i(1, 2, 3, 4));
    _TestVecCast<GfVec4f>(GfVec4h(1, 2, 3, 4));
    _TestVecCast<GfVec4d>(GfVec4h(1, 2, 3, 4));
    _TestVecCast<GfVec4d>(GfVec4f(1, 2, 3, 4));
    _TestVecCast<GfVec4h>(GfVec4f(1, 2, 3, 4));
    _TestVecCast<GfVec4h>(GfVec4d(1, 2, 3, 4));
    _TestVecCast<GfVec4f>(GfVec4d(1, 2, 3, 4));

    _FailVecCast<GfVec4i>(GfVec4h(1, 2, 3, 4));
    _FailVecCast<GfVec4i>(GfVec4f(1, 2, 3, 4));
    _FailVecCast<GfVec4i>(GfVec4d(1, 2, 3, 4));

    _FailVecCast<GfVec3i>(GfVec3h(1, 2, 3));
    _FailVecCast<GfVec3i>(GfVec3f(1, 2, 3));
    _FailVecCast<GfVec3i>(GfVec3d(1, 2, 3));

    _FailVecCast<GfVec2i>(GfVec2h(1, 2));
    _FailVecCast<GfVec2i>(GfVec2f(1, 2));
    _FailVecCast<GfVec2i>(GfVec2d(1, 2));

    // Equality special cases.

    v = VtValue();
    v2 = VtValue();

    if (!(v == v2))
        die("comparison with empty");

    v = VtValue(1.234);

    if (v == v2)
        die("comparison with empty");

    v2 = VtValue("hello");

    if (v == v2)
        die("comparison of mismatched types");

    v = VtValue(1234.0);
    v2 = VtValue(1234);
    if (v == v2)
        die("comparison of mismatched stack-held types");

    // Coverage

    v = VtValue();
    if (v.IsArrayValued())
        die("IsArrayValued for empty value");

    v = VtValue(1.234);
    if (v.IsArrayValued())
        die("scalar value reports it is shaped");

    v = VtValue(VtDoubleArray());
    if (!v.IsArrayValued())
        die("array value reports it is not an array");


    // Streaming...
    VtDictionary d;
    d["foo"] = 1.234;
    d["bar"] = "baz";

    vector<VtValue> vals;
    vals.push_back(VtValue(1.234));
    vals.push_back(VtValue("hello world"));

    std::ostringstream stream;
    stream << VtValue(d);
    if (stream.str().empty())
        die("couldn't stream value holding dictionary.");

    std::ostringstream stream2;
    stream2 << VtValue(vals);
    if (stream2.str().empty())
        die("couldn't stream value holding vector of values.");


    // Default stuff...
    TF_AXIOM(VtDictionaryGet<double>(d, "foo", VtDefault = 0) == 1.234);
    TF_AXIOM(VtDictionaryGet<double>(d, "noKey", VtDefault = 3.14) == 3.14);
    TF_AXIOM(VtDictionaryGet<string>(d, "bar", VtDefault = "hello") == "baz");
    TF_AXIOM(VtDictionaryGet<string>(d, "noKey", VtDefault = "bye") == "bye");


    // Casting a VtValue holding a TfToken to a string.
    {
        TfToken token("token");
        VtValue val(token);
        TF_AXIOM(val.IsHolding<TfToken>());
        val.Cast<string>();
        TF_AXIOM(val.IsHolding<string>());
        TF_AXIOM(val.Get<string>() == "token");
    }

    // Assignment and equality with string literals.
    {
        VtValue val;
        val = "hello";
        TF_AXIOM(val.IsHolding<string>());
        TF_AXIOM(val.Get<string>() == "hello");
        TF_AXIOM(val == "hello");
        TF_AXIOM("hello" == val);
    }

    // Equality
    {
        double d = 1.234, e = 2.71828;
        VtValue v(d);
        TF_AXIOM(v == d);
        TF_AXIOM(d == v);
        TF_AXIOM(v != e);
        TF_AXIOM(e != v);
    }

    // IsHolding<VtValue>
    {
        VtValue v(1.234);
        TF_AXIOM(v.IsHolding<double>());
        TF_AXIOM(v.IsHolding<VtValue>());
    }

    // Shapeliness and other stuff with non-stack-held arrays.
    {
        VtVec2iArray a(2), b(3);
        VtValue v(a);
        VtValue vclone(v);
        TF_AXIOM(v.Get<VtVec2iArray>().size() == 2);
        v = b;
        TF_AXIOM(v.Get<VtVec2iArray>().size() == 3);
        TF_AXIOM(v.IsArrayValued());
        TF_AXIOM(v.GetElementTypeid() == typeid(GfVec2i));
        TF_AXIOM(vclone.Get<VtVec2iArray>().size() == 2);
    }

    // Precision-casting of VtArrays
    {
        // only testing float <-> double... compound Vec types should
        // be the same
        VtFloatArray  fa(3), fRoundTripped;
        VtDoubleArray  da;

        fa[0] = 1.23456567;
        fa[1] = 4.63256635;
        fa[2] = 123443634.432;

        VtValue  v(fa);
        v.Cast<VtDoubleArray>();
        TF_AXIOM(v.IsHolding<VtDoubleArray>());
        da = v.UncheckedGet<VtDoubleArray>();

        VtValue vv(da);
        vv.Cast<VtFloatArray>();
        TF_AXIOM(vv.IsHolding<VtFloatArray>());
        fRoundTripped = vv.UncheckedGet<VtFloatArray>();
        // verify they compare euqal, but are physically two different arrays
        TF_AXIOM(fRoundTripped == fa);
        TF_AXIOM(!fRoundTripped.IsIdentical(fa));
    }

    // Test swapping VtValues holding dictionaries.
    {
        VtValue a, b;
        VtDictionary d1, d2;

        d1["foo"] = "bar";
        d2["bar"] = "foo";

        a = d1;
        b = d2;

        a.Swap(b);

        TF_AXIOM(a.Get<VtDictionary>().count("bar"));
        TF_AXIOM(b.Get<VtDictionary>().count("foo"));
    }

    // Test creating VtValues by taking contents of objects, and destructively
    // removing contents from objects.
    {
        string s("hello world!");
        VtValue v = VtValue::Take(s);
        TF_AXIOM(s.empty());
        TF_AXIOM(v.IsHolding<string>());
        TF_AXIOM(v.UncheckedGet<string>() == "hello world!");
        v.Swap(s);
        TF_AXIOM(v.IsHolding<string>());
        TF_AXIOM(v.UncheckedGet<string>().empty());
        TF_AXIOM(s == "hello world!");
        
        v.Swap(s);
        TF_AXIOM(v.IsHolding<string>() &&
                 v.UncheckedGet<string>() == "hello world!");
        string t = v.Remove<string>();
        TF_AXIOM(t == "hello world!");
        TF_AXIOM(v.IsEmpty());

        v.Swap(t);
        TF_AXIOM(t.empty());
        TF_AXIOM(v.IsHolding<string>() &&
                 v.UncheckedGet<string>() == "hello world!");

        t = v.UncheckedRemove<string>();
        TF_AXIOM(t == "hello world!");
        TF_AXIOM(v.IsEmpty());
    }

    // Test calling Get with incorrect type.  Should issue an error and produce
    // some "default" value.

    {
        VtValue empty;
        TfErrorMark m;
        TF_AXIOM(empty.Get<bool>() == false);
        TF_AXIOM(!m.IsClean());
    }

    {
        VtValue d(1.234);
        TfErrorMark m;
        TF_AXIOM(d.Get<double>() == 1.234);
        TF_AXIOM(m.IsClean());

        m.SetMark();
        TF_AXIOM(d.Get<int>() == 0);
        TF_AXIOM(!m.IsClean());
        
        m.SetMark();
        TF_AXIOM(d.Get<string>() == string());
        TF_AXIOM(!m.IsClean());
    }

}
Beispiel #17
0
void
HdxRenderTask::_Execute(HdTaskContext* ctx)
{
    HD_TRACE_FUNCTION();
    HD_MALLOC_TAG_FUNCTION();

    HdRenderPassStateSharedPtr renderPassState;

    if (_setupTask) {
        // if _setupTask exists (for backward compatibility), use it
        renderPassState = _setupTask->GetRenderPassState();
    } else {
        // otherwise, extract from TaskContext
        _GetTaskContextData(ctx, HdxTokens->renderPassState, &renderPassState);
    }
    if (not TF_VERIFY(renderPassState)) return;

    // Can't use GetTaskContextData because the lightingShader
    // is optional.
    VtValue lightingShader = (*ctx)[HdTokens->lightingShader];

    // it's possible to not set lighting shader to HdRenderPassState.
    // Hd_DefaultLightingShader will be used in that case.
    if (lightingShader.IsHolding<HdLightingShaderSharedPtr>()) {
        renderPassState->SetLightingShader(
            lightingShader.Get<HdLightingShaderSharedPtr>());
    }

    // Selection Setup
    // Note that selectionTask comes after renderTask, so that
    // it can access rprimIDs populated in RenderTask::_Sync.
    VtValue vo = (*ctx)[HdxTokens->selectionOffsets];
    VtValue vu = (*ctx)[HdxTokens->selectionUniforms];

    HdRenderPassShaderSharedPtr renderPassShader
        = renderPassState->GetRenderPassShader();

    if (not vo.IsEmpty() and not vu.IsEmpty()) {
        HdBufferArrayRangeSharedPtr obar
            = vo.Get<HdBufferArrayRangeSharedPtr>();
        HdBufferArrayRangeSharedPtr ubar
            = vu.Get<HdBufferArrayRangeSharedPtr>();

        renderPassShader->AddBufferBinding(
            HdBindingRequest(HdBinding::SSBO,
                             HdxTokens->selectionOffsets, obar,
                             /*interleave*/false));
        renderPassShader->AddBufferBinding(
            HdBindingRequest(HdBinding::UBO, 
                             HdxTokens->selectionUniforms, ubar,
                             /*interleave*/true));
    } else {
        renderPassShader->RemoveBufferBinding(HdxTokens->selectionOffsets);
        renderPassShader->RemoveBufferBinding(HdxTokens->selectionUniforms);
    }

    renderPassState->Bind();

    // execute all render passes.
    TF_FOR_ALL(it, _passes) {
        (*it)->Execute(renderPassState);
    }