Beispiel #1
0
/*
 * Return a FloatAttribute for points. There are 4 floats per
 * point, where the first 3 floats are the point's position,
 * and the 4th float is the weight of the point.
 */
static FnKat::FloatAttribute
_GetPwAttr(
    const UsdGeomNurbsPatch &nurbsPatch,
    double currentTime,
    const std::vector<double>& motionSampleTimes,
    const bool isMotionBackward)
{
    UsdAttribute weightsAttr = nurbsPatch.GetPointWeightsAttr();
    UsdAttribute pointsAttr = nurbsPatch.GetPointsAttr();

    if (!pointsAttr)
    {
        return FnKat::FloatAttribute();
    }

    FnKat::FloatBuilder pwBuilder(/* tupleSize = */ 4);
    TF_FOR_ALL(iter, motionSampleTimes)
    {
        double relSampleTime = *iter;
        double time = currentTime + relSampleTime;

        // Eval points at this motion sample time
        VtVec3fArray ptArray;
        pointsAttr.Get(&ptArray, time);
        // Eval Weights at this motion sample time
        VtDoubleArray wtArray;
        weightsAttr.Get(&wtArray, currentTime);
        
        bool hasWeights = false;
        if (ptArray.size() == wtArray.size())
        {
            hasWeights = true;
        }
        else if (wtArray.size() > 0)
        {
            FnLogWarn("Nurbs Patch " 
                    << nurbsPatch.GetPath().GetText()
                    << " has mismatched weights array. Skipping.");
            return FnKat::FloatAttribute();
        }

        // set the points data in katana at the give motion sample time
        std::vector<float> &ptVec = pwBuilder.get(isMotionBackward ?
            PxrUsdKatanaUtils::ReverseTimeSample(relSampleTime) : relSampleTime);

        ptVec.resize(ptArray.size() * 4);

        size_t count = 0;
        for (size_t i = 0; i != ptArray.size(); ++i)
        {
            float weight = hasWeights ? wtArray[i] : 1.0f;
            ptVec[count++] = ptArray[i][0]*weight;
            ptVec[count++] = ptArray[i][1]*weight;
            ptVec[count++] = ptArray[i][2]*weight;
            // the 4th float is the weight of the point
            ptVec[count++] = weight ;
        }
    }
static void testArray() {

    VtDoubleArray da(60);

    double val = 1;
    TF_FOR_ALL(elem, da)
        *elem = val++;

    val = 1;
    for (VtDoubleArray::const_iterator i = da.begin(); i != da.end(); ++i)
        if (*i != val++)
            die("iterator");

    // Do copy-on-write cases.
    VtDoubleArray da2 = da;
    da2[0] = 333.333;

    if (da2[0] != 333.333 || 
        da[0] == 333.333)
        die("copy-on-write");

    // Try swapping
    VtDoubleArray daCopy = da;
    VtDoubleArray da2Copy = da2;

    da.swap(da2);
    TF_AXIOM(da == da2Copy);
    TF_AXIOM(da2 == daCopy);

    using std::swap;
    swap(da, da2);
    TF_AXIOM(da == daCopy);
    TF_AXIOM(da2 == da2Copy);

    {
        // Try default-constructing a VtArray.
        VtDoubleArray def;
        TF_AXIOM(def.size() == 0);
        
        // Try iterating over the array.
        std::vector<double> v(def.begin(), def.end());
        TF_AXIOM(v.empty());

        // Test resizing a default constructed array.
        def.resize(123);
        TF_AXIOM(def.size() == 123);
    }

    {
        // Try creating an empty VtArray.
        VtDoubleArray array(0);
        TF_AXIOM(array.size() == 0);

        // Try iterating over the array.
        std::vector<double> v(array.begin(), array.end());
        TF_AXIOM(v.empty());
    }

    {
        // Array push_back and resize.
        VtDoubleArray array(0);

        // Push back on a rank-1 array.
        TF_AXIOM(array.size() == 0);
        array.push_back(1.234);
        TF_AXIOM(array.size() == 1);
        TF_AXIOM(array[0] == 1.234);

        array.push_back(2.3456);
        TF_AXIOM(array.size() == 2);
        TF_AXIOM(array[0] == 1.234);
        TF_AXIOM(array[1] == 2.3456);

        array.pop_back();
        TF_AXIOM(array.size() == 1);
        TF_AXIOM(array[0] == 1.234);

        // Resize should preserve elements.
        array.resize(100);
        TF_AXIOM(array.size() == 100);
        TF_AXIOM(array[0] == 1.234);
        TF_AXIOM(array[1] == 0.0);
        TF_AXIOM(array[50] == 0.0);
        TF_AXIOM(array[99] == 0.0);

        for (size_t i = 0; i != 100; ++i)
            array[i] = i;

        array.resize(1000);
        TF_AXIOM(array.size() == 1000);
        for (size_t i = 0; i != 1000; ++i) {
            if (i < 100) {
                TF_AXIOM(array[i] == i);
            } else {
                TF_AXIOM(array[i] == 0);
            }
        }

        array.resize(10);
        TF_AXIOM(array.size() == 10);
        for (size_t i = 0; i != 10; ++i) {
            TF_AXIOM(array[i] == i);
        }

        array.pop_back();
        array.pop_back();
        array.pop_back();
        array.pop_back();
        array.pop_back();

        TF_AXIOM(array.size() == 5);

    }

    {
        // Test that mutating shape data doesn't affect copies of an array.
        VtArray<int> a(4);
        a._GetShapeData()->otherDims[0] = 4;
        a._GetShapeData()->otherDims[1] = 0;

        VtArray<int> b = a;
        const auto &ca = a;
        const auto &cb = b;
        TF_AXIOM(ca._GetShapeData()->otherDims[0] ==
                 cb._GetShapeData()->otherDims[0]);
        TF_AXIOM(ca._GetShapeData()->otherDims[1] ==
                 cb._GetShapeData()->otherDims[1]);

        b._GetShapeData()->otherDims[0] = 2;
        b._GetShapeData()->otherDims[1] = 2;
        b._GetShapeData()->otherDims[2] = 0;

        // Check that a's shape data is unchanged
        TF_AXIOM(ca._GetShapeData()->otherDims[0] == 4);
        TF_AXIOM(ca._GetShapeData()->otherDims[1] == 0);

        // and that b's shape data has been updated as expected.
        TF_AXIOM(cb._GetShapeData()->otherDims[0] == 2);
        TF_AXIOM(cb._GetShapeData()->otherDims[1] == 2);
        TF_AXIOM(cb._GetShapeData()->otherDims[2] == 0);
    }
    
    {
        // Test initializer lists for VtArrays;
        VtArray<int> array1({1, 2, 3, 4});
        TF_AXIOM(array1.size() == 4);
        TF_AXIOM(array1[0] == 1);
        TF_AXIOM(array1[1] == 2);
        TF_AXIOM(array1[2] == 3);
        TF_AXIOM(array1[3] == 4);
        array1.assign({5, 6});
        TF_AXIOM(array1.size() == 2);
        TF_AXIOM(array1[0] == 5);
        TF_AXIOM(array1[1] == 6);
        array1.assign({});
        TF_AXIOM(array1.size() == 0);
        array1 = {7, 8, 9};
        TF_AXIOM(array1.size() == 3);
        TF_AXIOM(array1[0] == 7);
        TF_AXIOM(array1[1] == 8);
        TF_AXIOM(array1[2] == 9);
        array1 = {};
        TF_AXIOM(array1.size() == 0);
        
        VtArray<int> empty({});
        TF_AXIOM(empty.size() == 0);

        auto testImplicit = [](const VtArray<int>& array, size_t size) {
            TF_AXIOM(array.size() == size);
        };
        testImplicit({1,2,3}, 3);
    }

    {
        // Test VtArray -> TfSpan conversions.

        const VtIntArray constData({1,2,3,4,5});
        
        {
            VtIntArray copy(constData);

            TfSpan<const int> span = copy;
            // Make sure we didn't detach.
            TF_AXIOM(span.data() == constData.cdata());
            TF_AXIOM(span.size() == static_cast<std::ptrdiff_t>(copy.size()));
        }
        {
            VtIntArray copy(constData);

            auto span = TfMakeConstSpan(copy);
            // Make sure we didn't detach.
            TF_AXIOM(span.data() == constData.cdata());
            TF_AXIOM(span.size() == static_cast<std::ptrdiff_t>(copy.size()));
        }

        {
            VtIntArray copy(constData);

            TfSpan<int> span = copy;
            // Should have detached.
            TF_AXIOM(span.data() == copy.cdata() &&
                     span.data() != constData.cdata());
            TF_AXIOM(span.size() == static_cast<std::ptrdiff_t>(copy.size()));
        }

        {
            VtIntArray copy(constData);
            
            auto span = TfMakeSpan(copy);
            // Should have detached.
            TF_AXIOM(span.data() == copy.cdata() &&
                     span.data() != constData.cdata());
            TF_AXIOM(span.size() == static_cast<std::ptrdiff_t>(copy.size()));
        }
    }
}