Ejemplo n.º 1
0
void 
UsdImagingPointsAdapter::UpdateForTime(UsdPrim const& prim,
                                       SdfPath const& cachePath, 
                                       UsdTimeCode time,
                                       HdDirtyBits requestedBits,
                                       HdDirtyBits* resultBits,
                                       UsdImagingInstancerContext const* 
                                           instancerContext)
{
    BaseAdapter::UpdateForTime(
        prim, cachePath, time, requestedBits, resultBits, instancerContext);
    UsdImagingValueCache* valueCache = _GetValueCache();

    PrimvarInfoVector& primvars = valueCache->GetPrimvars(cachePath);

    VtValue& pointsValues = valueCache->GetPoints(cachePath);

    if (requestedBits & HdChangeTracker::DirtyPoints) {
        _GetPoints(prim, &pointsValues, time);
        UsdImagingValueCache::PrimvarInfo primvar;
        primvar.name = HdTokens->points;
        primvar.interpolation = UsdGeomTokens->vertex;
        _MergePrimvar(primvar, &primvars);
    }

    if (requestedBits & HdChangeTracker::DirtyWidths) {
        UsdImagingValueCache::PrimvarInfo primvar;
        UsdGeomPoints points(prim);
        VtFloatArray widths;
        primvar.name = UsdGeomTokens->widths;

        // XXX Add support for real constant interpolation
        primvar.interpolation = UsdGeomTokens->vertex;

        // Read the widths, if there is no widths create a buffer
        // and fill it with default widths of 1.0f
        if (!points.GetWidthsAttr().Get(&widths, time)) {

            // Check if we have just updated the points because in that
            // case we don't need to read the points again
            if (!(requestedBits & HdChangeTracker::DirtyPoints)) {
                _GetPoints(prim, &pointsValues, time);
            }

            for(size_t i = 0; i < pointsValues.Get<VtVec3fArray>().size() ; i ++) {
                widths.push_back(1.0f);
            }
        }
        _MergePrimvar(primvar, &primvars);
        valueCache->GetWidths(cachePath) = VtValue(widths);
    }
}
Ejemplo n.º 2
0
bool
UsdGeomCurves::ComputeExtent(const VtVec3fArray& points,
                             const VtFloatArray& widths, VtVec3fArray* extent)
{
    // We know nothing about the curve basis. Compute the extent as if it were
    // a point cloud with some max width (convex hull).
    float maxWidth = (widths.size() > 0 ?
                      *(std::max_element(widths.begin(), widths.end())) : 0);

    if (not UsdGeomPointBased::ComputeExtent(points, extent)) {
        return false;
    }

    GfVec3f widthVec = GfVec3f(maxWidth/2.);
    (*extent)[0] -= widthVec;
    (*extent)[1] += widthVec;

    return true;
}
Ejemplo n.º 3
0
 _UsdBuilder& SetSpline(std::string kat_prefix, std::string valueSuffix,
                        UsdRiSplineAPI spline) {
     // Knot count
     {
         UsdAttribute posAttr = spline.GetPositionsAttr();
         VtFloatArray posVec;
         posAttr.Get(&posVec);
         _builder.set(kat_prefix, FnKat::IntAttribute(posVec.size()));
     }
     // Knot positions
     Set( kat_prefix + "_Knots", spline.GetPositionsAttr() );
     // Knot values
     Set( kat_prefix + valueSuffix, spline.GetValuesAttr() );
     // Interpolation
     {
         VtValue val;
         UsdAttribute attr = spline.GetInterpolationAttr();
         if (attr.IsValid() && attr.HasAuthoredValueOpinion()
             && attr.Get(&val, _time) && val.IsHolding<TfToken>()) {
             TfToken t = val.Get<TfToken>();
             std::string interp = "unknown";
             if (t == UsdRiTokens->linear) {
                 interp = "linear";
             } else if (t == UsdRiTokens->catmullRom) {
                 interp = "catmull-rom";
             } else if (t == UsdRiTokens->bspline) {
                 interp = "bspline";
             } else if (t == UsdRiTokens->constant) {
                 interp = "constant";
             }
             _builder.set(kat_prefix + "_Interpolation",
                          FnKat::StringAttribute(interp));
         }
     }
     return *this;
 }
/* static */
bool
UsdMayaTranslatorMesh::_AssignColorSetPrimvarToMesh(
        const UsdGeomMesh& primSchema,
        const UsdGeomPrimvar& primvar,
        MFnMesh& meshFn)
{
    const TfToken& primvarName = primvar.GetPrimvarName();
    const SdfValueTypeName& typeName = primvar.GetTypeName();

    MString colorSetName(primvarName.GetText());

    // If the primvar is displayOpacity and it is a FloatArray, check if
    // displayColor is authored. If not, we'll import this 'displayOpacity'
    // primvar as a 'displayColor' color set. This supports cases where the
    // user created a single channel value for displayColor.
    // Note that if BOTH displayColor and displayOpacity are authored, they will
    // be imported as separate color sets. We do not attempt to combine them
    // into a single color set.
    if (primvarName == UsdMayaMeshColorSetTokens->DisplayOpacityColorSetName &&
            typeName == SdfValueTypeNames->FloatArray) {
        if (!UsdMayaRoundTripUtil::IsAttributeUserAuthored(primSchema.GetDisplayColorPrimvar())) {
            colorSetName = UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText();
        }
    }

    // We'll need to convert colors from linear to display if this color set is
    // for display colors.
    const bool isDisplayColor =
        (colorSetName == UsdMayaMeshColorSetTokens->DisplayColorColorSetName.GetText());

    // Get the raw data before applying any indexing. We'll only populate one
    // of these arrays based on the primvar's typeName, and we'll also set the
    // color representation so we know which array to use later.
    VtFloatArray alphaArray;
    VtVec3fArray rgbArray;
    VtVec4fArray rgbaArray;
    MFnMesh::MColorRepresentation colorRep;
    size_t numValues = 0;

    MStatus status = MS::kSuccess;

    if (typeName == SdfValueTypeNames->FloatArray) {
        colorRep = MFnMesh::kAlpha;
        if (!primvar.Get(&alphaArray) || alphaArray.empty()) {
            status = MS::kFailure;
        } else {
            numValues = alphaArray.size();
        }
    } else if (typeName == SdfValueTypeNames->Float3Array ||
               typeName == SdfValueTypeNames->Color3fArray) {
        colorRep = MFnMesh::kRGB;
        if (!primvar.Get(&rgbArray) || rgbArray.empty()) {
            status = MS::kFailure;
        } else {
            numValues = rgbArray.size();
        }
    } else if (typeName == SdfValueTypeNames->Float4Array ||
               typeName == SdfValueTypeNames->Color4fArray) {
        colorRep = MFnMesh::kRGBA;
        if (!primvar.Get(&rgbaArray) || rgbaArray.empty()) {
            status = MS::kFailure;
        } else {
            numValues = rgbaArray.size();
        }
    } else {
        TF_WARN("Unsupported color set primvar type '%s' for primvar '%s' on "
                "mesh: %s",
                typeName.GetAsToken().GetText(),
                primvarName.GetText(),
                primvar.GetAttr().GetPrimPath().GetText());
        return false;
    }

    if (status != MS::kSuccess || numValues == 0) {
        TF_WARN("Could not read color set values from primvar '%s' on mesh: %s",
                primvarName.GetText(),
                primvar.GetAttr().GetPrimPath().GetText());
        return false;
    }

    VtIntArray assignmentIndices;
    int unauthoredValuesIndex = -1;
    if (primvar.GetIndices(&assignmentIndices)) {
        // The primvar IS indexed, so the indices array is what determines the
        // number of color values.
        numValues = assignmentIndices.size();
        unauthoredValuesIndex = primvar.GetUnauthoredValuesIndex();
    }

    // Go through the color data and translate the values into MColors in the
    // colorArray, taking into consideration that indexed data may have been
    // authored sparsely. If the assignmentIndices array is empty then the data
    // is NOT indexed.
    // Note that with indexed data, the data is added to the arrays in ascending
    // component ID order according to the primvar's interpolation (ascending
    // face ID for uniform interpolation, ascending vertex ID for vertex
    // interpolation, etc.). This ordering may be different from the way the
    // values are ordered in the primvar. Because of this, we recycle the
    // assignmentIndices array as we go to store the new mapping from component
    // index to color index.
    MColorArray colorArray;
    for (size_t i = 0; i < numValues; ++i) {
        int valueIndex = i;

        if (i < assignmentIndices.size()) {
            // The data is indexed, so consult the indices array for the
            // correct index into the data.
            valueIndex = assignmentIndices[i];

            if (valueIndex == unauthoredValuesIndex) {
                // This component is unauthored, so just update the
                // mapping in assignmentIndices and then skip the value.
                // We don't actually use the value at the unassigned index.
                assignmentIndices[i] = -1;
                continue;
            }

            // We'll be appending a new value, so the current length of the
            // array gives us the new value's index.
            assignmentIndices[i] = colorArray.length();
        }

        GfVec4f colorValue(1.0);

        switch(colorRep) {
            case MFnMesh::kAlpha:
                colorValue[3] = alphaArray[valueIndex];
                break;
            case MFnMesh::kRGB:
                colorValue[0] = rgbArray[valueIndex][0];
                colorValue[1] = rgbArray[valueIndex][1];
                colorValue[2] = rgbArray[valueIndex][2];
                break;
            case MFnMesh::kRGBA:
                colorValue[0] = rgbaArray[valueIndex][0];
                colorValue[1] = rgbaArray[valueIndex][1];
                colorValue[2] = rgbaArray[valueIndex][2];
                colorValue[3] = rgbaArray[valueIndex][3];
                break;
            default:
                break;
        }

        if (isDisplayColor) {
            colorValue = UsdMayaColorSpace::ConvertLinearToMaya(colorValue);
        }

        MColor mColor(colorValue[0], colorValue[1], colorValue[2], colorValue[3]);
        colorArray.append(mColor);
    }

    // colorArray now stores all of the values and any unassigned components
    // have had their indices set to -1, so update the unauthored values index.
    unauthoredValuesIndex = -1;

    const bool clamped = UsdMayaRoundTripUtil::IsPrimvarClamped(primvar);

    status = meshFn.createColorSet(colorSetName, nullptr, clamped, colorRep);
    if (status != MS::kSuccess) {
        TF_WARN("Unable to create color set '%s' for mesh: %s",
                colorSetName.asChar(),
                meshFn.fullPathName().asChar());
        return false;
    }

    // Create colors on the mesh from the values we collected out of the
    // primvar. We'll assign mesh components to these values below.
    status = meshFn.setColors(colorArray, &colorSetName, colorRep);
    if (status != MS::kSuccess) {
        TF_WARN("Unable to set color data on color set '%s' for mesh: %s",
                colorSetName.asChar(),
                meshFn.fullPathName().asChar());
        return false;
    }

    const TfToken& interpolation = primvar.GetInterpolation();

    // Build an array of value assignments for each face vertex in the mesh.
    // Any assignments left as -1 will not be assigned a value.
    MIntArray colorIds = _GetMayaFaceVertexAssignmentIds(meshFn,
                                                         interpolation,
                                                         assignmentIndices,
                                                         unauthoredValuesIndex);

    status = meshFn.assignColors(colorIds, &colorSetName);
    if (status != MS::kSuccess) {
        TF_WARN("Could not assign color values to color set '%s' on mesh: %s",
                colorSetName.asChar(),
                meshFn.fullPathName().asChar());
        return false;
    }

    return true;
}
Ejemplo n.º 5
0
inline bool
TopologyRefinerFactory<PXR_NS::Converter>::assignComponentTags(
    Far::TopologyRefiner & refiner, PXR_NS::Converter const & converter) {

    PXR_NAMESPACE_USING_DIRECTIVE

    PxOsdMeshTopology const & topology = converter.topology;

    PxOsdSubdivTags const & tags = topology.GetSubdivTags();

    //
    // creases
    //

    // The sharpnesses can be defined either per-crease or per-edge.
    VtIntArray const creaseIndices = tags.GetCreaseIndices(),
                     creaseLengths = tags.GetCreaseLengths();
    VtFloatArray const creaseWeights = tags.GetCreaseWeights();

    size_t numCreaseSets = creaseLengths.size();
    bool perEdgeCrease = creaseWeights.size() != numCreaseSets;

    if (perEdgeCrease) {
        // validate per-edge crease.
        int numEdges = 0;
        for (size_t i = 0; i < numCreaseSets; ++i) {
            numEdges += creaseLengths[i] - 1;
        }
        if (creaseWeights.size() != static_cast<size_t>(numEdges)) {
            TF_WARN("Invalid length of crease sharpnesses (%s)\n",
                converter.name.GetText());
            numCreaseSets = 0;
        }
    }
    for (size_t i=0, cindex=0, sindex=0; i < numCreaseSets; ++i) {

        int numSegments = creaseLengths[i] - 1;

        for (int j = 0; j < numSegments; ++j) {
            int v0 = creaseIndices[cindex+j],
                v1 = creaseIndices[cindex+j+1];

            OpenSubdiv::Vtr::Index edge = refiner.GetLevel(0).FindEdge(v0, v1);
            if (edge==OpenSubdiv::Vtr::INDEX_INVALID) {
                TF_WARN("Set edge sharpness cannot find edge (%d-%d) (%s)",
                        v0, v1, converter.name.GetText());
            } else {
                setBaseEdgeSharpness(refiner,
                    edge, std::max(0.0f, creaseWeights[sindex]));
            }

            if (perEdgeCrease) ++sindex;
        }
        if (!perEdgeCrease) ++sindex;
        cindex += creaseLengths[i];
    }

    //
    // corners
    //

    VtIntArray const cornerIndices = tags.GetCornerIndices();
    VtFloatArray const cornerWeights = tags.GetCornerWeights();

    size_t numCorners = cornerIndices.size();

    if (cornerWeights.size() != numCorners) {
        TF_WARN("Invalid length of corner sharpnesses at prim %s\n",
            converter.name.GetText());
        numCorners = 0;
    }
    for (size_t i=0; i < numCorners; ++i) {
        int vert = cornerIndices[i];
        if (vert >= 0 && vert < refiner.GetLevel(0).GetNumVertices()) {
            setBaseVertexSharpness(refiner,
                vert, std::max(0.0f, cornerWeights[i]));
        } else {
            TF_WARN("Set vertex sharpness cannot find vertex (%d) (%s)",
                vert, converter.name.GetText());
        }
    }

    //
    // holes
    //

    VtIntArray const holeIndices = tags.GetHoleIndices();

    int numHoles = holeIndices.size();

    for (int i=0; i < numHoles; ++i) {
        int face = holeIndices[i];
        if (face >= 0 && face < refiner.GetLevel(0).GetNumFaces()) {
            setBaseFaceHole(refiner, face, true);
        } else {
            TF_WARN("Set hole cannot find face (%d) (%s)",
                face, converter.name.GetText());
        }
    }

    return true;
}