Ejemplo n.º 1
0
void
HdChangeTracker::TaskRemoved(SdfPath const& id)
{
    TF_DEBUG(HD_TASK_REMOVED).Msg("Task Removed: %s\n", id.GetText());
    _taskState.erase(id);
}
Ejemplo n.º 2
0
void
HdChangeTracker::InstancerRemoved(SdfPath const& id)
{
    TF_DEBUG(HD_INSTANCER_REMOVED).Msg("Instancer Removed: %s\n", id.GetText());
    _instancerState.erase(id);
}
Ejemplo n.º 3
0
void
HdChangeTracker::TaskInserted(SdfPath const& id)
{
    TF_DEBUG(HD_TASK_ADDED).Msg("Task Added: %s\n", id.GetText());
    _taskState[id] = AllDirty;
}
Ejemplo n.º 4
0
Archivo: path.cpp Proyecto: lvxejay/USD
SdfPathVector
SdfPath::GetConciseRelativePaths(const SdfPathVector& paths) {

    SdfPathVector primPaths;
    SdfPathVector anchors;
    SdfPathVector labels;

    // initialize the vectors
    TF_FOR_ALL(iter, paths) {

        if(!iter->IsAbsolutePath()) {
            TF_WARN("argument to GetConciseRelativePaths contains a relative path.");
            return paths;
        }

        // first, get the prim paths
        SdfPath primPath = iter->GetPrimPath();
        SdfPath anchor = primPath.GetParentPath();

        primPaths.push_back(primPath);
        anchors.push_back(anchor);

        // we have to special case root anchors, since MakeRelativePath can't handle them
        if(anchor == SdfPath::AbsoluteRootPath())
          labels.push_back(primPath);
        else
          labels.push_back(primPath.MakeRelativePath(anchor));

    }

    // each ambiguous path must be raised to its parent
    bool ambiguous;
    do {

        ambiguous = false;

        // the next iteration of labels
        SdfPathVector newAnchors;
        SdfPathVector newLabels;

        // find ambiguous labels
        for(size_t i=0;i<labels.size();++i) {

           int ok = true;

           // search for some other path that makes this one ambiguous
           for(size_t j=0;j<labels.size();++j) {
              if(i != j && labels[i] == labels[j] && primPaths[i] != primPaths[j]) {
                  ok = false;
                  break;
              }
           }

           if(!ok) {

               // walk the anchor up one node
               SdfPath newAnchor = anchors[i].GetParentPath();

               newAnchors.push_back(newAnchor);
               newLabels.push_back( newAnchor == SdfPath::AbsoluteRootPath() ? primPaths[i]
                                       : primPaths[i].MakeRelativePath( newAnchor ) );
               ambiguous = true;

           } else {
               newAnchors.push_back(anchors[i]);
               newLabels.push_back(labels[i]);
           }

        }

        anchors = newAnchors;
        labels = newLabels;

    } while(ambiguous);

    // generate the final set from the anchors
    SdfPathVector result;

    for(size_t i=0; i<anchors.size();++i) {

       if(anchors[i] == SdfPath::AbsoluteRootPath()) {
          result.push_back( paths[i] );
       } else {
          result.push_back( paths[i].MakeRelativePath( anchors[i] ));
       }

    }

    return result;

}
Ejemplo n.º 5
0
void
HdChangeTracker::InstancerInserted(SdfPath const& id)
{
    TF_DEBUG(HD_INSTANCER_ADDED).Msg("Instancer Added: %s\n", id.GetText());
    _instancerState[id] = AllDirty;
}
Ejemplo n.º 6
0
std::string Item::getPath() const
{
    SdfPath path = m_prim.GetPath();
    return path.GetString();
}
Ejemplo n.º 7
0
SdfAttributeSpecHandle
SdfAttributeSpec::_New(
    const SdfRelationshipSpecHandle& owner,
    const SdfPath& path,
    const std::string& name,
    const SdfValueTypeName& typeName,
    SdfVariability variability,
    bool custom)
{
    if (!owner) {
        TF_CODING_ERROR("NULL owner");
        return TfNullPtr;
    }
    if (!typeName) {
        TF_CODING_ERROR("Cannot create attribute spec <%s> with invalid type",
                        owner->GetPath().AppendTarget(path).
                            AppendProperty(TfToken(name)).GetText());
	return TfNullPtr;
    }

    SdfChangeBlock block;

    // Determine the path of the relationship target
    SdfPath absPath = path.MakeAbsolutePath(owner->GetPath().GetPrimPath());
    SdfPath targetPath = owner->GetPath().AppendTarget(absPath);

    // Check to make sure that the name is valid
    if (!Sdf_ChildrenUtils<Sdf_AttributeChildPolicy>::IsValidName(name)) {
        TF_CODING_ERROR(
            "Cannot create attribute on %s with invalid name: %s",
            targetPath.GetText(), name.c_str());
        return TfNullPtr;
    }

    // Create the relationship target if it doesn't already exist. Note
    // that this does not automatically get added to the relationship's
    // target path list.
    SdfSpecHandle targetSpec = owner->_FindOrCreateTargetSpec(path);

    // AttributeSpecs are considered initially to have only required fields 
    // only if they are not custom.
    bool hasOnlyRequiredFields = (!custom);

    // Create the relational attribute spec
    SdfPath attrPath = targetPath.AppendRelationalAttribute(TfToken(name));
    if (!Sdf_ChildrenUtils<Sdf_AttributeChildPolicy>::CreateSpec(
            owner->GetLayer(), attrPath, SdfSpecTypeAttribute, 
            hasOnlyRequiredFields)) {
        return TfNullPtr;
    }

    SdfAttributeSpecHandle spec =
        owner->GetLayer()->GetAttributeAtPath(attrPath);
    
    // Avoid expensive dormancy checks in the case of binary-backed data.
    SdfAttributeSpec *specPtr = get_pointer(spec);
    if (TF_VERIFY(specPtr)) {
        specPtr->SetField(SdfFieldKeys->Custom, custom);
        specPtr->SetField(SdfFieldKeys->TypeName, typeName.GetAsToken());
        specPtr->SetField(SdfFieldKeys->Variability, variability);
    }

    return spec;
}
Ejemplo n.º 8
0
HdTextureResource::ID
UsdImagingGL_GetTextureResourceID(UsdPrim const& usdPrim,
                                  SdfPath const& usdPath,
                                  UsdTimeCode time,
                                  size_t salt)
{
    if (!TF_VERIFY(usdPrim)) {
        return HdTextureResource::ID(-1);
    }
    if (!TF_VERIFY(usdPath != SdfPath())) {
        return HdTextureResource::ID(-1);
    }

    // If the texture name attribute doesn't exist, it might be badly specified
    // in scene data.
    UsdAttribute attr = _GetTextureResourceAttr(usdPrim, usdPath);

    SdfAssetPath asset;
    if (!attr || !attr.Get(&asset, time)) {
        TF_WARN("Unable to find texture attribute <%s> in scene data",
                usdPath.GetText());
        return HdTextureResource::ID(-1);
    }

    HdTextureType textureType = HdTextureType::Uv;
    TfToken filePath = TfToken(asset.GetResolvedPath());

    if (!filePath.IsEmpty()) {
        // If the resolved path contains a correct path, then we are 
        // dealing with a ptex or uv textures.
        if (GlfIsSupportedPtexTexture(filePath)) {
            textureType = HdTextureType::Ptex;
        } else {
            textureType = HdTextureType::Uv;
        }
    } else {
        // If the path couldn't be resolved, then it might be a Udim as they 
        // contain special characters in the path to identify them <Udim>.
        // Another option is that the path is just wrong and it can not be
        // resolved.
        filePath = TfToken(asset.GetAssetPath());
        if (GlfIsSupportedUdimTexture(filePath)) {
            const GlfContextCaps& caps = GlfContextCaps::GetInstance();
            if (!UsdImaging_UdimTilesExist(filePath, caps.maxArrayTextureLayers,
                _FindLayerHandle(attr, time))) {
                TF_WARN("Unable to find Texture '%s' with path '%s'. Fallback "
                        "textures are not supported for udim",
                        filePath.GetText(), usdPath.GetText());
                return HdTextureResource::ID(-1);
            }
            if (!caps.arrayTexturesEnabled) {
                TF_WARN("OpenGL context does not support array textures, "
                        "skipping UDIM Texture %s with path %s.",
                        filePath.GetText(), usdPath.GetText());
                return HdTextureResource::ID(-1);
            }
            textureType = HdTextureType::Udim;
        } else if (GlfIsSupportedPtexTexture(filePath)) {
            TF_WARN("Unable to find Texture '%s' with path '%s'. Fallback "
                    "textures are not supported for ptex",
                    filePath.GetText(), usdPath.GetText());
            return HdTextureResource::ID(-1);
        } else {
            TF_WARN("Unable to find Texture '%s' with path '%s'. A black "
                    "texture will be substituted in its place.",
                    filePath.GetText(), usdPath.GetText());
            return HdTextureResource::ID(-1);
        }
    }

    GlfImage::ImageOriginLocation origin =
            UsdImagingGL_ComputeTextureOrigin(usdPrim);

    // Hash on the texture filename.
    size_t hash = asset.GetHash();

    // Hash in wrapping and filtering metadata.
    HdWrap wrapS = _GetWrapS(usdPrim, textureType);
    HdWrap wrapT = _GetWrapT(usdPrim, textureType);
    HdMinFilter minFilter = _GetMinFilter(usdPrim);
    HdMagFilter magFilter = _GetMagFilter(usdPrim);
    float memoryLimit = _GetMemoryLimit(usdPrim);

    boost::hash_combine(hash, origin);
    boost::hash_combine(hash, wrapS);
    boost::hash_combine(hash, wrapT);
    boost::hash_combine(hash, minFilter);
    boost::hash_combine(hash, magFilter);
    boost::hash_combine(hash, memoryLimit);

    // Salt the result to prevent collisions in non-shared imaging.
    // Note that the salt is ignored for fallback texture hashes above.
    boost::hash_combine(hash, salt);

    return HdTextureResource::ID(hash);
}
Ejemplo n.º 9
0
HdTextureResourceSharedPtr
UsdImagingGL_GetTextureResource(UsdPrim const& usdPrim,
                                SdfPath const& usdPath,
                                UsdTimeCode time)
{
    if (!TF_VERIFY(usdPrim))
        return HdTextureResourceSharedPtr();
    if (!TF_VERIFY(usdPath != SdfPath()))
        return HdTextureResourceSharedPtr();

    UsdAttribute attr = _GetTextureResourceAttr(usdPrim, usdPath);
    SdfAssetPath asset;
    if (!TF_VERIFY(attr) || !TF_VERIFY(attr.Get(&asset, time))) {
        return HdTextureResourceSharedPtr();
    }

    HdTextureType textureType = HdTextureType::Uv;

    TfToken filePath = TfToken(asset.GetResolvedPath());
    // If the path can't be resolved, it's either an UDIM texture
    // or the texture doesn't exists and we can to exit early.
    if (filePath.IsEmpty()) {
        filePath = TfToken(asset.GetAssetPath());
        if (GlfIsSupportedUdimTexture(filePath)) {
            textureType = HdTextureType::Udim;
        } else {
            TF_DEBUG(USDIMAGING_TEXTURES).Msg(
                "File does not exist, returning nullptr");
            TF_WARN("Unable to find Texture '%s' with path '%s'.",
                    filePath.GetText(), usdPath.GetText());
            return {};
        }
    } else {
        if (GlfIsSupportedPtexTexture(filePath)) {
            textureType = HdTextureType::Ptex;
        }
    }

    GlfImage::ImageOriginLocation origin =
            UsdImagingGL_ComputeTextureOrigin(usdPrim);

    HdWrap wrapS = _GetWrapS(usdPrim, textureType);
    HdWrap wrapT = _GetWrapT(usdPrim, textureType);
    HdMinFilter minFilter = _GetMinFilter(usdPrim);
    HdMagFilter magFilter = _GetMagFilter(usdPrim);
    float memoryLimit = _GetMemoryLimit(usdPrim);

    TF_DEBUG(USDIMAGING_TEXTURES).Msg(
            "Loading texture: id(%s), type(%s)\n",
            usdPath.GetText(),
            textureType == HdTextureType::Uv ? "Uv" :
            textureType == HdTextureType::Ptex ? "Ptex" : "Udim");
 
    HdTextureResourceSharedPtr texResource;
    TfStopwatch timer;
    timer.Start();
    // Udim's can't be loaded through like other textures, because
    // we can't select the right factory based on the file type.
    // We also need to pass the layer context to the factory,
    // so each file gets resolved properly.
    GlfTextureHandleRefPtr texture;
    if (textureType == HdTextureType::Udim) {
        UdimTextureFactory factory(_FindLayerHandle(attr, time));
        texture = GlfTextureRegistry::GetInstance().GetTextureHandle(
            filePath, origin, &factory);
    } else {
        texture = GlfTextureRegistry::GetInstance().GetTextureHandle(
            filePath, origin);
    }

    texResource = HdTextureResourceSharedPtr(
        new HdStSimpleTextureResource(texture, textureType, wrapS, wrapT,
                                      minFilter, magFilter, memoryLimit));
    timer.Stop();

    TF_DEBUG(USDIMAGING_TEXTURES).Msg("    Load time: %.3f s\n", 
                                     timer.GetSeconds());

    return texResource;
}
Ejemplo n.º 10
0
 static _Key _GetKey(const SdfPath& path)
 {
     return path.IsTargetPath() ? _Key(path.GetTargetPath())
                                : _Key(path.GetNameToken());
 }
Ejemplo n.º 11
0
bool
SdfBatchNamespaceEdit::Process(
    SdfNamespaceEditVector* processedEdits,
    const HasObjectAtPath& hasObjectAtPath,
    const CanEdit& canEdit,
    SdfNamespaceEditDetailVector* details,
    bool fixBackpointers) const
{
    // Clear the resulting edits -- we'll build up the result as we go.
    if (processedEdits) {
        processedEdits->clear();
    }

    // Track edits as we check them.
    SdfNamespaceEdit_Namespace ns(fixBackpointers);

    // Try each edit in sequence.
    for (const auto& edit : GetEdits()) {
        // Make sure paths are compatible.
        bool mismatch = false;
        if (edit.currentPath.IsPrimPath()) {
            mismatch = !edit.newPath.IsPrimPath();
        }
        else if (edit.currentPath.IsPropertyPath()) {
            mismatch = !edit.newPath.IsPropertyPath();
        }
        else {
            // Unsupported path type.
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          "Unsupported object type"));
            }
            return false;
        }
        if (mismatch && !edit.newPath.IsEmpty()) {
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          "Path type mismatch"));
            }
            return false;
        }

        // Get the original path for the object now at edit.currentPath.
        const SdfPath& from = ns.FindOrCreateOriginalPath(edit.currentPath);

        // Can't edit from removed namespace except if we're removing.
        // We allow the exception so it works to, say, remove a prim then
        // its properties rather than removing its properties then the prim.
        if (from.IsEmpty()) {
            if (edit.newPath.IsEmpty()) {
                // This edit has already happened so it's allowed.  Do not
                // record it in processedEdits.
                continue;
            }
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          "Object was removed"));
            }
            return false;
        }

        // Make sure there's an object at from.
        if (hasObjectAtPath && !hasObjectAtPath(from)) {
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          "Object does not exist"));
            }
            return false;
        }

        // Extra checks if not removing.
        SdfPath to;
        if (!edit.newPath.IsEmpty()) {
            // Ignore no-op.  Note that this doesn't catch the case where
            // then index isn't Same but has that effect.  
            if (edit.currentPath == edit.newPath && 
                    edit.index == SdfNamespaceEdit::Same) {
                continue;
            }

            // Get the original path for the object now at edit.newPath's
            // parent.
            SdfPath newParent = edit.newPath.GetParentPath();
            const SdfPath& toParent = ns.FindOrCreateOriginalPath(newParent);

            // Can't move under removed namespace.
            if (toParent.IsEmpty()) {
                if (details) {
                    details->push_back(
                        SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                              edit,
                                              "New parent was removed"));
                }
                return false;
            }

            // Make sure there is an object at to's parent.
            if (hasObjectAtPath && !hasObjectAtPath(toParent)) {
                if (details) {
                    details->push_back(
                        SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                              edit,
                                              "New parent does not exist"));
                }
                return false;
            }

            // Check for impossible namespace structure.
            if (edit.currentPath == edit.newPath) {
                // Ignore reordering.
            }
            else if (edit.currentPath.HasPrefix(edit.newPath)) {
                // Making object an ancestor of itself.
                if (details) {
                    details->push_back(
                        SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                              edit,
                                              "Object cannot be an ancestor "
                                              "of itself"));
                }
                return false;
            }
            else if (edit.newPath.HasPrefix(edit.currentPath)) {
                // Making object a descendant of itself.
                if (details) {
                    details->push_back(
                        SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                              edit,
                                              "Object cannot be a descendant "
                                              "of itself"));
                }
                return false;
            }
            else {
                // Can't move over an existing object.
                to = ns.GetOriginalPath(edit.newPath);
                if (!to.IsEmpty() && 
                    hasObjectAtPath && hasObjectAtPath(to)) {
                    if (details) {
                        details->push_back(
                            SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                                  edit,
                                                  "Object already exists"));
                    }
                    return false;
                }
            }

            // Get the real to path.
            to = edit.newPath.ReplacePrefix(newParent, toParent);
        }

        if (!fixBackpointers) {
            SdfPathVector targetPaths;

            edit.currentPath.GetAllTargetPathsRecursively(&targetPaths);
            for (const auto& targetPath : targetPaths) {
                SdfPath originalPath = ns.GetOriginalPath(targetPath);
                if (!originalPath.IsEmpty() && originalPath != targetPath) {
                    if (details) {
                        details->push_back(
                            SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                                  edit,
                                                  "Current target was edited"));
                    }
                    return false;
                }
            }

            edit.newPath.GetAllTargetPathsRecursively(&targetPaths);
            for (const auto& targetPath : targetPaths) {
                SdfPath originalPath = ns.GetOriginalPath(targetPath);
                if (!originalPath.IsEmpty() && originalPath != targetPath) {
                    if (details) {
                        details->push_back(
                            SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                                  edit,
                                                  "New target was edited"));
                    }
                    return false;
                }
            }
        }

        // Check if actual edit is allowed.
        std::string whyNot;
        if (canEdit && !canEdit(SdfNamespaceEdit(from, to, edit.index),
                                    &whyNot)) {
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          whyNot));
            }
            return false;
        }

        // Apply edit to state.
        if (!ns.Apply(edit, &whyNot)) {
            if (details) {
                details->push_back(
                    SdfNamespaceEditDetail(SdfNamespaceEditDetail::Error,
                                          edit,
                                          whyNot));
            }
            return false;
        }

        // Save this edit.
        if (processedEdits) {
            processedEdits->push_back(edit);
        }
    }

    // Analyze processedEdits.
    if (processedEdits) {
        // XXX: We'd like to compute a minimal sequence of edits but for
        //      now we just return the input sequence.  The primary
        //      complication with a minimal sequence is that edits may
        //      overlap in namespace so they must be ordered to avoid
        //      illegal edits and incorrect results.  For example if
        //      we start with /A/B and /A/C and rename C to D then B to
        //      C we must maintain that order, otherwise we'd rename B
        //      to C when there's already an object named C.
        //
        //      To make matters worse, if the above had a final rename
        //      D to B then the final result is to exchange the names of
        //      B and C.  We can't eliminate the C to D rename even
        //      though D does not appear in the final result because
        //      exchanging names is not a valid operation and no ordering
        //      of two operations yields the correct result.
        //
        //      Another requirement is that children must be added to a
        //      parent in the input order to ensure the right final
        //      ordering.  (That's only relevant for prims.)
        //
        //      A final requirement is that removed objects first be
        //      edited to their final location before removal.  This
        //      allows the client to know that final location to fix up
        //      backpointers before making them dangle.  Clients may
        //      not need to keep dangling backpointers but we can't
        //      know that here.
    }

    return true;
}
Ejemplo n.º 12
0
Archivo: path.cpp Proyecto: lvxejay/USD
SdfPath
SdfPath::MakeAbsolutePath(const SdfPath & anchor) const {

    if (anchor == SdfPath()) {
        TF_WARN("MakeAbsolutePath(): anchor is the empty path.");
        return SdfPath();
    }

    // Check that anchor is an absolute path
    if (!anchor.IsAbsolutePath()) {
        TF_WARN("MakeAbsolutePath() requires an absolute path as an argument.");
        return SdfPath();
    }

    // Check that anchor is a component path
    if (!anchor.IsAbsoluteRootOrPrimPath() && 
        !anchor.IsPrimVariantSelectionPath()) {
        TF_WARN("MakeAbsolutePath() requires a prim path as an argument.");
        return SdfPath();
    }

    // If we're invalid, just return a copy of ourselves.
    if (IsEmpty())
        return *this;

    SdfPath result = *this;

    // If we're not already absolute, do our own path using anchor as the
    // relative base.
    if (!IsAbsolutePath()) {
        // This list winds up in reverse order to what one might at
        // first expect.
        vector<Sdf_PathNodeConstRefPtr> relNodes;

        Sdf_PathNodeConstRefPtr relRoot = Sdf_PathNode::GetRelativeRootNode();
        Sdf_PathNodeConstRefPtr curNode = _pathNode;
        // Walk up looking for oldPrefix node.
        while (curNode) {
            if (curNode == relRoot) {
                break;
            }
            relNodes.push_back(curNode);
            curNode = curNode->GetParentNode();
        }
        if (!curNode) {
            // Didn't find relative root
            // should never get here since all relative paths should have a
            // relative root node
            // CODE_COVERAGE_OFF
            TF_CODING_ERROR("Didn't find relative root");
            return SdfPath();
            // CODE_COVERAGE_ON
        }

        result = anchor;

        // Got the list, now add nodes similar to relNodes to anchor
        // relNodes needs to be iterated in reverse since the closest ancestor
        // node was pushed on last.
        vector<Sdf_PathNodeConstRefPtr>::reverse_iterator it = relNodes.rbegin();
        while (it != relNodes.rend()) {
            result = _AppendNode(result, *it);
            ++it;
        }
    }

    // Now make target path absolute (recursively) if we need to.
    // We need to use result's prim path as the anchor for the target path.
    SdfPath const &targetPath = result.GetTargetPath();
    if (!targetPath.IsEmpty()) {
        SdfPath primPath = result.GetPrimPath();
        SdfPath newTargetPath = targetPath.MakeAbsolutePath(primPath);
        result = result.ReplaceTargetPath(newTargetPath);
    }

    return result;
}
Ejemplo n.º 13
0
Archivo: path.cpp Proyecto: lvxejay/USD
SdfPath
SdfPath::_ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix,
                       bool fixTargetPaths) const
{
    if (*this == oldPrefix) {
        // Base case: we've reached oldPrefix.
        return newPrefix;
    }

    if (GetPathElementCount() == 0) {
        // Empty paths have nothing to replace.
        return *this;
    }

    // If we've recursed above the oldPrefix, we can bail as long as there
    // are no target paths we need to fix.
    if (GetPathElementCount() <= oldPrefix.GetPathElementCount() &&
        (!fixTargetPaths || !_pathNode->ContainsTargetPath())) {
        // We'll never see oldPrefix beyond here, so return.
        return *this;
    }

    // Recursively translate the parent.
    SdfPath parent =
        GetParentPath()._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths);

    // Translation of the parent may fail; it will have emitted an error.
    // Return here so we don't deref an invalid _pathNode below.
    if (parent.IsEmpty())
        return SdfPath();

    // Append the tail component.  Use _AppendNode() except in these cases:
    // - For prims and properties, we construct child nodes directly
    //   so as to not expand out ".." components and to avoid the cost
    //   of unnecessarily re-validating identifiers.
    // - For embedded target paths, translate the target path.
    switch (_pathNode->GetNodeType()) {
    case Sdf_PathNode::PrimNode:
        return SdfPath(Sdf_PathNode::FindOrCreatePrim(parent._pathNode,
                                                    _pathNode->GetName()));
    case Sdf_PathNode::PrimPropertyNode:
        return SdfPath(Sdf_PathNode::FindOrCreatePrimProperty(
                                parent._pathNode, _pathNode->GetName()));
    case Sdf_PathNode::TargetNode:
        if (fixTargetPaths) {
            return parent.AppendTarget( _pathNode->GetTargetPath()
                ._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths));
        } else {
            return _AppendNode(parent, _pathNode);
        }
    case Sdf_PathNode::MapperNode:
        if (fixTargetPaths) {
            return parent.AppendMapper( _pathNode->GetTargetPath()
                ._ReplacePrefix(oldPrefix, newPrefix, fixTargetPaths));
        } else {
            return _AppendNode(parent, _pathNode);
        }
    default:
        return _AppendNode(parent, _pathNode);
    }
}
Ejemplo n.º 14
0
Archivo: path.cpp Proyecto: lvxejay/USD
// Overload hash_value for SdfPath.
size_t hash_value(SdfPath const &path) {
    return path.GetHash();
}
Ejemplo n.º 15
0
void
HdChangeTracker::BprimInserted(SdfPath const& id, HdDirtyBits initialDirtyState)
{
    TF_DEBUG(HD_BPRIM_ADDED).Msg("Bprim Added: %s\n", id.GetText());
    _bprimState[id] = initialDirtyState;
}
Ejemplo n.º 16
0
void 
GusdRefiner::addPrimitive( const GT_PrimitiveHandle& gtPrimIn )
{
    if(!gtPrimIn) {
        std::cout << "Attempting to add invalid prim" << std::endl;
        return;
    }
    GT_PrimitiveHandle gtPrim = gtPrimIn;     // copy to a non-const handle
    int primType = gtPrim->getPrimitiveType();
    DBG( cerr << "GusdRefiner::addPrimitive, " << gtPrim->className() << endl );
    
    string primName;
    // Types can register a function to provide a prim name. 
    // Volumes do this to return a name stored in the f3d file. This is 
    // important for consistant cluster naming.
    string n;
    if( GusdPrimWrapper::getPrimName( gtPrim, n )) {
        primName = n;
    }

    bool refinePackedPrims = m_refinePackedPrims;
    bool primHasNameAttr = false;
    if( primName.empty() ) {

        GT_AttributeListHandle primAttrs;
        if( primType == GT_GEO_PACKED ) {
            primAttrs = UTverify_cast<const GT_GEOPrimPacked*>(gtPrim.get())->getInstanceAttributes();

        } 
        if( !primAttrs ) {
            primAttrs = gtPrim->getUniformAttributes();
        }
        if( !primAttrs ) {
            primAttrs = gtPrim->getDetailAttributes();
        }

        GT_DataArrayHandle dah;
        if( primAttrs ) {
            dah = primAttrs->get( m_pathAttrName.c_str() );
        }

        if( dah && dah->isValid() ) {
            const char *s = dah->getS(0);
            if( s != NULL ) {
                primName = s;
                primHasNameAttr = true;
            }
        }
        if( primAttrs ) {
            GT_DataArrayHandle overXformsAttr = primAttrs->get( GUSD_OVERTRANSFORMS_ATTR );
            if( overXformsAttr ) {
                if( overXformsAttr->getI32(0) != 0 ) {
                    refinePackedPrims = false;
                }
            }
        }
    }

    
    // The following is only necessary for point instancers. Prototypes 
    // can't be point instancers.
    if (!m_buildPrototypes) {

        // Check per prim if we are building a point instancer. This may cause
        // problems for point instancers with discontiguous packed prims.
        bool localBuildPointInstancer = false;
        // If we have imported USD geometry get the type to see if it is a
        // point instancer we need to overlay.
        if(auto packedUSD = dynamic_cast<const GusdGT_PackedUSD*>( gtPrim.get() )) {
            if(packedUSD->getFileName()) {

                // Get the usd src prim path used for point instancers
                const SdfPath& instancerPrimPath =
                    packedUSD->getSrcPrimPath();

                GusdStageCacheReader cache;
                if(UsdPrim prim = cache.GetPrimWithVariants(
                    packedUSD->getFileName(), instancerPrimPath).first) {
                    // Get the type name of the usd file to overlay
                    m_pointInstancerType = prim.GetTypeName();
            
                    // Make sure to set buildPointInstancer to true if we are overlaying a
                    // point instancer
                    if (m_pointInstancerType == _tokens->PointInstancer ||
                        m_pointInstancerType == _tokens->PxPointInstancer) {
                        localBuildPointInstancer = true;
                    }
                }
            }
        }
        // If we find either an instancepath or usdinstancepath attribute, build a
        // point instancer.
        GT_Owner owner;
        if(gtPrim->findAttribute("instancepath", owner, 0) ||
            gtPrim->findAttribute("usdinstancepath", owner, 0) ) {
            localBuildPointInstancer = true;
        }

        if (m_buildPointInstancer || localBuildPointInstancer) {
            // If we are building point instancer, stash prims that can be 
            // point instanced. Build the point instancer in the finish method.
            
            // If given a prim path, pass it to the collector for a custom
            // usd scope. Otherwise pass an empty SdfPath.
            SdfPath instancerPrimPath;
            if( !primName.empty() ) {
                instancerPrimPath = SdfPath(createPrimPath(primName));
            }

            if( auto packedUSD = dynamic_cast<const GusdGT_PackedUSD*>( gtPrim.get() )) {
                // Point instancer from packed usd
                instancerPrimPath = instancerPrimPath.IsEmpty() ? packedUSD->getSrcPrimPath() : instancerPrimPath;
                m_collector.addInstPrim( instancerPrimPath, gtPrim );
                return;
            }
            else if( gtPrim->getPrimitiveType() == GT_PRIM_INSTANCE ) {
                // Point instancer from packed primitives

                // A GT_PrimInstance can container more than one instance. Create 
                // an entry for each.
                auto instPrim = UTverify_cast<const GT_PrimInstance*>( gtPrim.get() );

                // TODO: If we put all geometry packed prims here, then we break
                // grouping prims for purpose
                for( size_t i = 0; i < instPrim->entries(); ++i ) {
                    m_collector.addInstPrim( instancerPrimPath, gtPrim, i );
                }
                return;
            }

            if( primType == GT_PRIM_PARTICLE || primType == GT_PRIM_POINT_MESH ) {
                // Point instancer from points with instancepath attribute

                // Check for the usdprototypespath attribute in case it is not
                // a point or primitivie attribute.
                GT_AttributeListHandle uniformAttrs = gtPrim->getUniformAttributes();
                uniformAttrs = findAndAddStringAttribute(uniformAttrs, "usdprototypespath", gtPrim);

                // Find and add a custom prototype scope attribute.
                uniformAttrs = findAndAddStringAttribute(uniformAttrs, "usdprototypesscope", gtPrim);

                gtPrim = new GusdGT_PointInstancer( 
                                    gtPrim->getPointAttributes(), 
                                    uniformAttrs );
                primType = gtPrim->getPrimitiveType();
            }
        }
    }
    // We must refine packed prims that don't have a name
    if( !primHasNameAttr && !refinePackedPrims ) {
        refinePackedPrims = true;
    }

    if( primName.empty() && 
        gtPrim->getPrimitiveType() == GusdGT_PackedUSD::getStaticPrimitiveType() ) {

        auto packedUsdPrim = UTverify_cast<const GusdGT_PackedUSD *>(gtPrim.get());
        SdfPath path = packedUsdPrim->getPrimPath().StripAllVariantSelections();
        if( m_useUSDIntrinsicNames ) {
            primName = path.GetString();
        }
        else {
            primName = path.GetName();
        }

        // We want prototypes to be children of the point instancer, so we make 
        // the usd path a relative scope of just the usd prim name
        if ( m_buildPrototypes && !primName.empty() && primName[0] == '/' ) {
            size_t idx = primName.find_last_of("/");
            primName = primName.substr(idx+1);
        } 
    }
    // If the prim path was not explicitly set, try to come up with a reasonable
    // default.
    bool addNumericSuffix = false;
    if( primName.empty() ) {

        int t = gtPrim->getPrimitiveType();
        if( t == GT_PRIM_POINT_MESH || t == GT_PRIM_PARTICLE )
            primName = "points";
        else if( t == GT_PRIM_POLYGON_MESH || t == GT_PRIM_SUBDIVISION_MESH )
            primName = "mesh";
        else if( t == GT_PRIM_CURVE_MESH )
            primName = "curve";
        else if( t == GusdGT_PointInstancer::getStaticPrimitiveType() )
            primName = "instances";
        else if(const char *n = GusdPrimWrapper::getUsdName( t ))
            primName = n;
        else
            primName = "obj";
        
        if( !primName.empty() ) {
            addNumericSuffix = true;
        }
    }

    string primPath = createPrimPath(primName);

    TfToken purpose = UsdGeomTokens->default_;
    {
        GT_Owner own = GT_OWNER_PRIMITIVE;
        GT_DataArrayHandle dah = gtPrim->findAttribute( GUSD_PURPOSE_ATTR, own, 0 );
        if( dah && dah->isValid() ) {
            purpose = TfToken(dah->getS(0));
        }
    }

    if( primType == GT_PRIM_INSTANCE ) {
 
       auto inst = UTverify_cast<const GT_PrimInstance*>(gtPrim.get());
        const GT_PrimitiveHandle geometry = inst->geometry();

        if ( geometry->getPrimitiveType() == GT_GEO_PACKED ) {

            // If we find a packed prim that has a name, this become a group (xform) in 
            // USD. If it doesn't have a name, we just accumulate the transform and recurse.

            auto packedGeo = UTverify_cast<const GT_GEOPrimPacked*>(geometry.get());
            for( GT_Size i = 0; i < inst->transforms()->entries(); ++i ) {

                UT_Matrix4D m;
                inst->transforms()->get(i)->getMatrix(m);

                UT_Matrix4D newCtm = m_localToWorldXform;
                newCtm = m* m_localToWorldXform;

                SdfPath newPath = m_pathPrefix;
                bool recurse = true;

                if( primHasNameAttr || 
                    ( m_forceGroupTopPackedPrim && m_isTopLevel )) {

                    // m_forceGroupTopPackedPrim is used when we are writing instance 
                    // prototypes. We need to add instance id attributes to the top 
                    // level group. Here we make sure that we create that group, even 
                    // if the user hasn't named it.

                    newPath = m_collector.add(  SdfPath(primPath), 
                                                addNumericSuffix,
                                                gtPrim,
                                                newCtm,
                                                purpose,
                                                m_writeCtrlFlags );
            
                    // If we are just writing transforms and encounter a packed prim, we 
                    // just want to write it's transform and not refine it further.
                    recurse = refinePackedPrims;
                }

                if( recurse ) {
                    GusdRefiner childRefiner(
                                    m_collector,
                                    newPath,
                                    m_pathAttrName,
                                    newCtm );
                    
                    childRefiner.m_refinePackedPrims = refinePackedPrims;
                    childRefiner.m_forceGroupTopPackedPrim = m_forceGroupTopPackedPrim;
                    childRefiner.m_isTopLevel = false;

                    childRefiner.m_writeCtrlFlags = m_writeCtrlFlags;
                    childRefiner.m_writeCtrlFlags.update( geometry );

#if UT_MAJOR_VERSION_INT >= 16
                    childRefiner.refineDetail( packedGeo->getPackedDetail(), m_refineParms );
#else
                    childRefiner.refineDetail( packedGeo->getPrim()->getPackedDetail(), m_refineParms );
#endif
                }
            }
            return;
        }
    }

    if( (primType != GT_GEO_PACKED || !refinePackedPrims) && 
                            GusdPrimWrapper::isGTPrimSupported(gtPrim) ) {

        UT_Matrix4D m;
        if( primType == GT_GEO_PACKED ) {
            // packed fragment
            UTverify_cast<const GT_GEOPrimPacked*>(gtPrim.get())->getFullTransform()->getMatrix(m);
        }
        else {
            gtPrim->getPrimitiveTransform()->getMatrix(m);
        }

        UT_Matrix4D newCtm = m_localToWorldXform;
        newCtm = m* m_localToWorldXform;

        m_collector.add( SdfPath(primPath),
                         addNumericSuffix,
                         gtPrim,
                         newCtm,
                         purpose,
                         m_writeCtrlFlags );
    }
    else {
        gtPrim->refine( *this, &m_refineParms );
    }
}
/// Finds the existing SkelRoot which is shared by all \p paths.
/// If no SkelRoot is found, and \p config is "auto", then attempts to
/// find a common ancestor of \p paths which can be converted to SkelRoot.
/// \p outMadeSkelRoot must be non-null; it will be set to indicate whether
/// any auto-typename change actually occurred (true) or whether there was
/// already a SkelRoot, so no renaming was necessary (false).
/// If an existing, common SkelRoot cannot be found for all paths, and if
/// it's not possible to create one, returns an empty SdfPath.
static SdfPath
_VerifyOrMakeSkelRoot(const UsdStagePtr& stage,
                      const SdfPath& path,
                      const TfToken& config)
{
    if (config != UsdMayaJobExportArgsTokens->auto_ &&
        config != UsdMayaJobExportArgsTokens->explicit_) {
        return SdfPath();
    }

    // Only try to auto-rename to SkelRoot if we're not already a
    // descendant of one. Otherwise, verify that the user tagged it in a sane
    // way.

    if (UsdSkelRoot root = UsdSkelRoot::Find(stage->GetPrimAtPath(path))) {

        // Verify that the SkelRoot isn't nested in another SkelRoot.
        // This is necessary because UsdSkel doesn't handle nested skel roots
        // very well currently; this restriction may be loosened in the future.
        if (UsdSkelRoot root2 = UsdSkelRoot::Find(root.GetPrim().GetParent())) {
            TF_RUNTIME_ERROR("The SkelRoot <%s> is nested inside another "
                    "SkelRoot <%s>. This might cause unexpected behavior.",
                    root.GetPath().GetText(), root2.GetPath().GetText());
            return SdfPath();
        }
        else {
            return root.GetPath();
        }
    } else if(config == UsdMayaJobExportArgsTokens->auto_) {
        // If auto-generating the SkelRoot, find the rootmost
        // UsdGeomXform and turn it into a SkelRoot.
        // XXX: It might be good to also consider model hierarchy here, and not
        // go past our ancestor component when trying to generate the SkelRoot.
        // (Example: in a scene with /World, /World/Char_1, /World/Char_2, we
        // might want SkelRoots to stop at Char_1 and Char_2.) Unfortunately,
        // the current structure precludes us from accessing model hierarchy
        // here.
        if (UsdPrim root = _FindRootmostXformOrSkelRoot(stage, path)) {
            UsdSkelRoot::Define(stage, root.GetPath());
            return root.GetPath();
        }
        else {
            if (path.IsRootPrimPath()) {
                // This is the most common problem when we can't obtain a
                // SkelRoot.
                // Show a nice error with useful information about root prims.
                TF_RUNTIME_ERROR("The prim <%s> is a root prim, so it has no "
                        "ancestors that can be converted to a SkelRoot. (USD "
                        "requires that skinned meshes and skeletons be "
                        "encapsulated under a SkelRoot.) Try grouping this "
                        "prim under a parent group.",
                        path.GetText());
            }
            else {
                // Show generic error as a last resort if we don't know exactly
                // what went wrong.
                TF_RUNTIME_ERROR("Could not find an ancestor of the prim <%s> "
                        "that can be converted to a SkelRoot. (USD requires "
                        "that skinned meshes and skeletons be encapsulated "
                        "under a SkelRoot.)",
                        path.GetText());
            }
            return SdfPath();
        }
    }
    return SdfPath();
}
void 
Sdf_ConnectionListEditor<ChildPolicy>::_OnEditShared(
    SdfListOpType op,
    SdfSpecType specType,
    const std::vector<SdfPath>& oldItems, 
    const std::vector<SdfPath>& newItems) const
{
    // XXX The following code tries to manage lifetime of the target
    // specs associated with this list, but it slightly buggy: if
    // multiple lists mention the same target -- ex. if a target is
    // added, appended, and prepended -- then this proxy for a single
    // list has no way to know if the target also exists in those
    // other lists, and so it cannot mangae lifetime on its own.

    if (op == SdfListOpTypeOrdered || op == SdfListOpTypeDeleted) {
        // These ops do not affect target spec lifetime, so there's
        // nothing to do.
        return;
    }

    const SdfPath propertyPath = GetPath();
    SdfLayerHandle layer = GetLayer();
    const std::set<value_type> oldItemSet(oldItems.begin(), oldItems.end());
    const std::set<value_type> newItemSet(newItems.begin(), newItems.end());

    // Need to remove all children in oldItems that are not in newItems.
    std::vector<SdfPath> childrenToRemove;
    std::set_difference(oldItemSet.begin(), oldItemSet.end(),
                        newItemSet.begin(), newItemSet.end(), 
                        std::back_inserter(childrenToRemove));
    TF_FOR_ALL(child, childrenToRemove) {
        if (!Sdf_ChildrenUtils<ChildPolicy>::RemoveChild(
                layer, propertyPath, *child)) {
            // Some data backends procedurally generate the children specs based
            // on the listops as an optimization, so if we failed to remove a
            // child here, it could be that.  If no spec is present, then we
            // consider things to be okay and do not issue an error.
            const SdfPath specPath = 
                ChildPolicy::GetChildPath(propertyPath, *child);
            if (layer->GetObjectAtPath(specPath)) {
                TF_CODING_ERROR("Failed to remove spec at <%s>",
                                specPath.GetText());
            }
        }
    }

    // Need to add all children in newItems that are not in oldItems.
    std::vector<SdfPath> childrenToAdd;
    std::set_difference(newItemSet.begin(), newItemSet.end(), 
                        oldItemSet.begin(), oldItemSet.end(),
                        std::back_inserter(childrenToAdd));
    TF_FOR_ALL(child, childrenToAdd) {
        const SdfPath specPath = ChildPolicy::GetChildPath(propertyPath, *child);
        if (layer->GetObjectAtPath(specPath)) {
            continue;
        }

        if (!Sdf_ChildrenUtils<ChildPolicy>::CreateSpec(layer, specPath,
                specType)) {
            TF_CODING_ERROR("Failed to create spec at <%s>", specPath.GetText());
        }
    }
}
Ejemplo n.º 19
0
PxrUsdMayaShadingModeExportContext::AssignmentVector
PxrUsdMayaShadingModeExportContext::GetAssignments() const
{
    AssignmentVector ret;

    MStatus status;
    MFnDependencyNode seDepNode(_shadingEngine, &status);
    if (!status) {
        return ret;
    }

    MPlug dsmPlug = seDepNode.findPlug("dagSetMembers", true, &status);
    if (!status) {
        return ret;
    }

    SdfPathSet seenBoundPrimPaths;
    for (unsigned int i = 0; i < dsmPlug.numConnectedElements(); i++) {
        MPlug dsmElemPlug(dsmPlug.connectionByPhysicalIndex(i));
        MStatus status = MS::kFailure;
        MFnDagNode dagNode(PxrUsdMayaUtil::GetConnected(dsmElemPlug).node(), &status);
        if (!status) {
            continue;
        }

        MDagPath dagPath;
        if (!dagNode.getPath(dagPath))
            continue;

        SdfPath usdPath = PxrUsdMayaUtil::MDagPathToUsdPath(dagPath, 
            _mergeTransformAndShape);

        // If _overrideRootPath is not empty, replace the root namespace with it
        if (!_overrideRootPath.IsEmpty() ) {
            usdPath = usdPath.ReplacePrefix(usdPath.GetPrefixes()[0], _overrideRootPath);
        }
        
        // If this path has already been processed, skip it.
        if (!seenBoundPrimPaths.insert(usdPath).second)
            continue;

        // If the bound prim's path is not below a bindable root, skip it.
        if (SdfPathFindLongestPrefix(_bindableRoots.begin(), 
            _bindableRoots.end(), usdPath) == _bindableRoots.end()) {
            continue;
        }

        MObjectArray sgObjs, compObjs;
        // Assuming that instancing is not involved.
        status = dagNode.getConnectedSetsAndMembers(0, sgObjs, compObjs, true);
        if (!status)
            continue;

        for (size_t j = 0; j < sgObjs.length(); j++) {
            // If the shading group isn't the one we're interested in, skip it.
            if (sgObjs[j] != _shadingEngine)
                continue;

            VtIntArray faceIndices;
            if (!compObjs[j].isNull()) {
                MItMeshPolygon faceIt(dagPath, compObjs[j]);
                faceIndices.reserve(faceIt.count());
                for ( faceIt.reset() ; !faceIt.isDone() ; faceIt.next() ) {
                    faceIndices.push_back(faceIt.index());
                }
            }
            ret.push_back(std::make_pair(usdPath, faceIndices));
        }
    }
    return ret;
}
Ejemplo n.º 20
0
TfToken usdWriteJob::writeVariants(const UsdPrim &usdRootPrim)
{
    // Init parameters for filtering and setting the active variant
    std::string defaultModelingVariant;

    // Get the usdVariantRootPrimPath (optionally filter by renderLayer prefix)
    MayaPrimWriterPtr firstPrimWriterPtr = *mJobCtx.mMayaPrimWriterList.begin();
    std::string firstPrimWriterPathStr( firstPrimWriterPtr->getDagPath().fullPathName().asChar() );
    std::replace( firstPrimWriterPathStr.begin(), firstPrimWriterPathStr.end(), '|', '/');
    std::replace( firstPrimWriterPathStr.begin(), firstPrimWriterPathStr.end(), ':', '_'); // replace namespace ":" with "_"
    SdfPath usdVariantRootPrimPath(firstPrimWriterPathStr);
    usdVariantRootPrimPath = usdVariantRootPrimPath.GetPrefixes()[0];

    // Create a new usdVariantRootPrim and reference the Base Model UsdRootPrim
    //   This is done for reasons as described above under mArgs.usdModelRootOverridePath
    UsdPrim usdVariantRootPrim = mJobCtx.mStage->DefinePrim(usdVariantRootPrimPath);
    TfToken defaultPrim = usdVariantRootPrim.GetName();
    usdVariantRootPrim.GetReferences().AppendInternalReference(usdRootPrim.GetPath());
    usdVariantRootPrim.SetActive(true);
    usdRootPrim.SetActive(false);

    // Loop over all the renderLayers
    for (unsigned int ir=0; ir < mRenderLayerObjs.length(); ++ir) {
        SdfPathTable<bool> tableOfActivePaths;
        MFnRenderLayer renderLayerFn( mRenderLayerObjs[ir] );
        MString renderLayerName = renderLayerFn.name();
        std::string variantName(renderLayerName.asChar());
        // Determine default variant. Currently unsupported
        //MPlug renderLayerDisplayOrderPlug = renderLayerFn.findPlug("displayOrder", true);
        //int renderLayerDisplayOrder = renderLayerDisplayOrderPlug.asShort();
                    
        // The Maya default RenderLayer is also the default modeling variant
        if (mRenderLayerObjs[ir] == MFnRenderLayer::defaultRenderLayer()) {
            defaultModelingVariant=variantName;
        }
        
        // Make the renderlayer being looped the current one
        MGlobal::executeCommand(MString("editRenderLayerGlobals -currentRenderLayer ")+
                                        renderLayerName, false, false);

        // == ModelingVariants ==
        // Identify prims to activate
        // Put prims and parent prims in a SdfPathTable
        // Then use that membership to determine if a prim should be Active.
        // It has to be done this way since SetActive(false) disables access to all child prims.
        MObjectArray renderLayerMemberObjs;
        renderLayerFn.listMembers(renderLayerMemberObjs);
        std::vector< SdfPath > activePaths;
        for (unsigned int im=0; im < renderLayerMemberObjs.length(); ++im) {
            MFnDagNode dagFn(renderLayerMemberObjs[im]);
            MDagPath dagPath;
            dagFn.getPath(dagPath);
            dagPath.extendToShape();
            SdfPath usdPrimPath; 
            if (!TfMapLookup(mDagPathToUsdPathMap, dagPath, &usdPrimPath)) {
                continue;
            }
            usdPrimPath = usdPrimPath.ReplacePrefix(usdPrimPath.GetPrefixes()[0], usdVariantRootPrimPath); // Convert base to variant usdPrimPath
            tableOfActivePaths[usdPrimPath] = true;
            activePaths.push_back(usdPrimPath);
            //UsdPrim usdPrim = mStage->GetPrimAtPath(usdPrimPath);
            //usdPrim.SetActive(true);
        }
        if (!tableOfActivePaths.empty()) {
            { // == BEG: Scope for Variant EditContext
                // Create the variantSet and variant
                UsdVariantSet modelingVariantSet = usdVariantRootPrim.GetVariantSets().AppendVariantSet("modelingVariant");
                modelingVariantSet.AppendVariant(variantName);
                modelingVariantSet.SetVariantSelection(variantName);
                // Set the Edit Context
                UsdEditTarget editTarget = modelingVariantSet.GetVariantEditTarget();
                UsdEditContext editContext(mJobCtx.mStage, editTarget);

                // == Activate/Deactivate UsdPrims
                UsdPrimRange rng = UsdPrimRange::AllPrims(mJobCtx.mStage->GetPseudoRoot());
                std::vector<UsdPrim> primsToDeactivate;
                for (auto it = rng.begin(); it != rng.end(); ++it) {
                    UsdPrim usdPrim = *it;
                    // For all xformable usdPrims...
                    if (usdPrim && usdPrim.IsA<UsdGeomXformable>()) {
                        bool isActive=false;
                        for (size_t j=0;j<activePaths.size();j++) {
                            //primPathD.HasPrefix(primPathA);
                            SdfPath activePath=activePaths[j];
                            if (usdPrim.GetPath().HasPrefix(activePath) || activePath.HasPrefix(usdPrim.GetPath())) {
                                isActive=true; break;
                            }
                        }
                        if (isActive==false) {
                            primsToDeactivate.push_back(usdPrim);
                            it.PruneChildren();
                        }
                    }
                }
                // Now deactivate the prims (done outside of the UsdPrimRange 
                // so not to modify the iterator while in the loop)
                for ( UsdPrim const& prim : primsToDeactivate ) {
                    prim.SetActive(false);
                }
            } // == END: Scope for Variant EditContext
        }
    } // END: RenderLayer iterations

    // Set the default modeling variant
    UsdVariantSet modelingVariantSet = usdVariantRootPrim.GetVariantSet("modelingVariant");
    if (modelingVariantSet.IsValid()) {
        modelingVariantSet.SetVariantSelection(defaultModelingVariant);
    }
    return defaultPrim;
}
Ejemplo n.º 21
0
void
SdfAttributeSpec::ChangeMapperPath(
    const SdfPath& oldPath, const SdfPath& newPath)
{
    if (!PermissionToEdit()) {
        TF_CODING_ERROR("Change mapper path: Permission denied.");
        return;
    }

    const SdfPath& attrPath = GetPath();

    // Absolutize.
    SdfPath oldAbsPath = oldPath.MakeAbsolutePath(attrPath.GetPrimPath());
    SdfPath newAbsPath = newPath.MakeAbsolutePath(attrPath.GetPrimPath());

    // Validate.
    if (oldAbsPath == newAbsPath) {
        // Nothing to do.
        return;
    }
    if (!newAbsPath.IsPropertyPath()) {
        TF_CODING_ERROR("cannot change connection path for attribute %s's "
                        "mapper at connection path <%s> to <%s> because it's "
                        "not a property path",
                        attrPath.GetString().c_str(),
                        oldAbsPath.GetString().c_str(),
                        newAbsPath.GetString().c_str());
        return;
    }
    
    SdfPathVector mapperPaths = 
        GetFieldAs<SdfPathVector>(SdfChildrenKeys->MapperChildren);

    // Check that a mapper actually exists at the old path.
    SdfPathVector::iterator mapperIt = 
        std::find(mapperPaths.begin(), mapperPaths.end(), oldAbsPath);
    if (mapperIt == mapperPaths.end()) {
        TF_CODING_ERROR("Change mapper path: No mapper exists for "
            "connection path <%s>.", oldAbsPath.GetText());
        return;
    }

    // Check that no mapper already exists at the new path.
    const bool mapperExistsAtNewPath = 
        (std::find(mapperPaths.begin(), mapperPaths.end(), newAbsPath) != 
            mapperPaths.end());
    if (mapperExistsAtNewPath) {
        TF_CODING_ERROR("Change mapper path: Mapper already exists for "
            "connection path <%s>.", newAbsPath.GetText());
        return;
    }

    // Things look OK -- let's go ahead and move the mapper over to the
    // new path.
    SdfChangeBlock block;
        
    const SdfPath oldMapperSpecPath = attrPath.AppendMapper(oldAbsPath);
    const SdfPath newMapperSpecPath = attrPath.AppendMapper(newAbsPath);
    _MoveSpec(oldMapperSpecPath, newMapperSpecPath);

    *mapperIt = newAbsPath;
    SetField(SdfChildrenKeys->MapperChildren, VtValue(mapperPaths));

}
Ejemplo n.º 22
0
Archivo: path.cpp Proyecto: lvxejay/USD
SdfPath
SdfPath::MakeRelativePath(const SdfPath & anchor) const
{
    TRACE_FUNCTION();

    // Check that anchor is a valid path
    if ( anchor == SdfPath() ) {
        TF_WARN("MakeRelativePath(): anchor is the invalid path.");
        return SdfPath();
    }

    // Check that anchor is an absolute path
    if (!anchor.IsAbsolutePath()) {
        TF_WARN("MakeRelativePath() requires an absolute path as an argument.");
        return SdfPath();
    }

    // Check that anchor is a component path
    if (!anchor.IsAbsoluteRootOrPrimPath() && !anchor.IsPrimVariantSelectionPath()) {
        TF_WARN("MakeRelativePath() requires a component path as an argument (got '%s').",
                 anchor.GetString().c_str());
        return SdfPath();
    }

    // If we're invalid, just return a copy of ourselves.
    if (!_pathNode) {
        return SdfPath();
    }

    if (!IsAbsolutePath()) {
        // Canonicalize... make sure the relative path has the
        // fewest possible dot-dots.
        SdfPath absPath = MakeAbsolutePath(anchor);

        return absPath.MakeRelativePath(anchor);
    }

    // We are absolute, we want to be relative

    // This list winds up in reverse order to what one might at first expect.
    vector<Sdf_PathNodeConstRefPtr> relNodes;

    // We need to crawl up the this path until we are the same length as
    // the anchor.
    // Then we crawl up both till we find the matching nodes.
    // As we crawl, we build the relNodes vector.
    size_t thisCount = _pathNode->GetElementCount();
    size_t anchorCount = anchor._pathNode->GetElementCount();

    // these pointers avoid construction/destruction
    // of ref pointers
    Sdf_PathNodeConstRefPtr curThisNode = _pathNode;
    Sdf_PathNodeConstRefPtr curAnchorNode = anchor._pathNode;

    // walk to the same depth
    size_t dotdotCount = 0;

    while (thisCount > anchorCount) {
        relNodes.push_back(curThisNode);
        curThisNode = curThisNode->GetParentNode();
        --thisCount;
    }

    while (thisCount < anchorCount) {
        ++dotdotCount;
        curAnchorNode = curAnchorNode->GetParentNode();
        --anchorCount;
    }

    // now we're at the same depth
    TF_AXIOM(thisCount == anchorCount);

    // walk to a common prefix
    while (curThisNode != curAnchorNode) {
        ++dotdotCount;
        relNodes.push_back(curThisNode);
        curThisNode   = curThisNode->GetParentNode();
        curAnchorNode = curAnchorNode->GetParentNode();
    }

    // Now relNodes the nodes of this path after the prefix
    // common to anchor and this path.
    SdfPath result = ReflexiveRelativePath();

    // Start by adding dotdots
    while (dotdotCount--) {
        result = result.GetParentPath();
    }

    // Now add nodes similar to relNodes to the ReflexiveRelativePath()
    // relNodes needs to be iterated in reverse since the closest ancestor
    // node was pushed on last.
    vector<Sdf_PathNodeConstRefPtr>::reverse_iterator it = relNodes.rbegin();
    while (it != relNodes.rend()) {
        result = _AppendNode(result, *it);
        ++it;
    }

    return result;
}