예제 #1
0
파일: wrapXformable.cpp 프로젝트: MWDD/USD
PXR_NAMESPACE_CLOSE_SCOPE

// ===================================================================== //
// Feel free to add custom code below this line, it will be preserved by 
// the code generator.  The entry point for your custom code should look
// minimally like the following:
//
// WRAP_CUSTOM {
//     _class
//         .def("MyCustomMethod", ...)
//     ;
// }
//
// Of course any other ancillary or support code may be provided.
// 
// Just remember to wrap code in the appropriate delimiters:
// 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
//
// ===================================================================== //
// --(BEGIN CUSTOM CODE)--

#include "pxr/base/tf/pyEnum.h"

PXR_NAMESPACE_OPEN_SCOPE

static GfMatrix4d
_GetLocalTransformation1(const UsdGeomXformable &self,
                        const UsdTimeCode time) 
{
    GfMatrix4d result(1);
    bool resetsXformStack;
    self.GetLocalTransformation(&result, &resetsXformStack, time);
    return result;
}
예제 #2
0
파일: wrapXformable.cpp 프로젝트: MWDD/USD
static std::vector<double>
_GetTimeSamples(const UsdGeomXformable &self)
{
    std::vector<double> result;
    self.GetTimeSamples(&result);
    return result;
}
예제 #3
0
파일: examples.cpp 프로젝트: 400dama/USD
//! [CreateMatrixWithDefault]
bool CreateMatrixWithDefault(UsdGeomXformable const &gprim, GfMatrix4d const &defValue)
{
    if (UsdGeomXformOp transform = gprim.MakeMatrixXform()){
        return transform.Set(defValue, UsdTimeCode::Default());
    } else {
        return false;
    }
}
예제 #4
0
static GfMatrix4d
_GetLocalTransformation1(const UsdGeomXformable &self,
                        const UsdTimeCode time) 
{
    GfMatrix4d result(1);
    bool resetsXformStack;
    self.GetLocalTransformation(&result, &resetsXformStack, time);
    return result;
}
예제 #5
0
파일: wrapXformable.cpp 프로젝트: MWDD/USD
static GfMatrix4d
_GetLocalTransformation2(const UsdGeomXformable &self,
                         const std::vector<UsdGeomXformOp> &ops,
                         const UsdTimeCode time) 
{
    GfMatrix4d result(1);
    bool resetsXformStack;
    self.GetLocalTransformation(&result, &resetsXformStack, ops, time);
    return result;
}
예제 #6
0
파일: examples.cpp 프로젝트: 400dama/USD
//! [CreateAnimatedTransform]
bool CreateAnimatedTransform(UsdGeomXformable const &gprim, 
                             GfVec3d const &baseTranslate,
                             GfVec3f const &baseRotateXYZ,
                             GfVec3f const &defPivot)
{
    // Only need to do this if you're overriding an existing scene
    if (not gprim.ClearXformOpOrder()){
        return false;
    }
    
    static const TfToken  pivSuffix("pivot");
    UsdGeomXformOp    trans = gprim.AddTranslateOp();
    UsdGeomXformOp    pivot = gprim.AddTranslateOp(UsdGeomXformOp::PrecisionFloat,
                                                   pivSuffix);
    UsdGeomXformOp   rotate = gprim.AddRotateXYZOp();
    UsdGeomXformOp pivotInv = gprim.AddTranslateOp(UsdGeomXformOp::PrecisionFloat,
                                                   pivSuffix,
                                                   /* isInverseOp = */ true);
    // Now that we have created all the ops, set default values.
    // Note that we do not need to (and cannot) set the value
    // for the pivot's inverse op.
    // For didactic brevity we are eliding success return value checks,
    // but would absolutely have them in exporters!
    trans.Set(baseTranslate, UsdTimeCode::Default());
    pivot.Set(defPivot, UsdTimeCode::Default());
    rotate.Set(baseRotateXYZ, UsdTimeCode::Default());
    
    // Now animate the translation and rotation over a fixed interval with
    // cheesy linear animation.
    GfVec3d  position(baseTranslate);
    GfVec3f  rotation(baseRotateXYZ);
    
    for (double frame = 0; frame < 100.0; frame += 1.0){
        trans.Set(position, frame);
        rotate.Set(rotation, frame);
        position[0] += 5.0;
        rotation[2] += 7.0;
    }
    return true;
}
예제 #7
0
UsdGeomXformable::XformQuery::XformQuery(const UsdGeomXformable &xformable):
    _resetsXformStack(false)
{
    vector<UsdGeomXformOp> orderedXformOps =
        xformable.GetOrderedXformOps(&_resetsXformStack);

    if (not orderedXformOps.empty()) {
        _xformOps = orderedXformOps;

        // Create attribute queries for all the xform ops.
        TF_FOR_ALL(it, _xformOps) {
            it->_CreateAttributeQuery();
        }
    }
예제 #8
0
파일: wrapXformable.cpp 프로젝트: MWDD/USD
static UsdAttribute
_CreateXformOpOrderAttr(UsdGeomXformable &self,
                                      object defaultVal, bool writeSparsely) {
    return self.CreateXformOpOrderAttr(
        UsdPythonToSdfType(defaultVal, SdfValueTypeNames->TokenArray), writeSparsely);
}
예제 #9
0
파일: wrapXformable.cpp 프로젝트: MWDD/USD
static std::vector<UsdGeomXformOp>
_GetOrderedXformOps(const UsdGeomXformable &self)
{
    bool resetsXformStack=false;
    return self.GetOrderedXformOps(&resetsXformStack);
}
예제 #10
0
// Populate the AnimationChannel vector with various ops based on the Maya
// transformation logic If scale and/or rotate pivot are declared, create
// inverse ops in the appropriate order
void MayaTransformWriter::pushTransformStack(
        const MFnTransform& iTrans, 
        const UsdGeomXformable& usdXformable, 
        bool writeAnim)
{   
    // NOTE: I think this logic and the logic in MayaTransformReader
    // should be merged so the concept of "CommonAPI" stays centralized.
    //
    // By default we assume that the xform conforms to the common API
    // (xlate,pivot,rotate,scale,pivotINVERTED) As soon as we encounter any
    // additional xform (compensation translates for pivots, rotateAxis or
    // shear) we are not conforming anymore 
    bool conformsToCommonAPI = true;

    // Keep track of where we have rotate and scale Pivots and their inverse so
    // that we can combine them later if possible
    unsigned int rotPivotIdx = -1, rotPivotINVIdx = -1, scalePivotIdx = -1, scalePivotINVIdx = -1;
    
    // Check if the Maya prim inheritTransform
    MPlug inheritPlug = iTrans.findPlug("inheritsTransform");
    if (!inheritPlug.isNull()) {
        if(!inheritPlug.asBool()) {
            usdXformable.SetResetXformStack(true);
        }
    }
            
    // inspect the translate, no suffix to be closer compatibility with common API
    _GatherAnimChannel(TRANSLATE, iTrans, "translate", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inspect the rotate pivot translate
    if (_GatherAnimChannel(TRANSLATE, iTrans, "rotatePivotTranslate", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // inspect the rotate pivot
    bool hasRotatePivot = _GatherAnimChannel(TRANSLATE, iTrans, "rotatePivot", "X", "Y", "Z", &mAnimChanList, writeAnim, true);
    if (hasRotatePivot) {
        rotPivotIdx = mAnimChanList.size()-1;
    }

    // inspect the rotate, no suffix to be closer compatibility with common API
    _GatherAnimChannel(ROTATE, iTrans, "rotate", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inspect the rotateAxis/orientation
    if (_GatherAnimChannel(ROTATE, iTrans, "rotateAxis", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // invert the rotate pivot
    if (hasRotatePivot) {
        AnimChannel chan;
        chan.usdOpType = UsdGeomXformOp::TypeTranslate;
        chan.precision = UsdGeomXformOp::PrecisionFloat;
        chan.opName = "rotatePivot";
        chan.isInverse = true;
        mAnimChanList.push_back(chan);
        rotPivotINVIdx = mAnimChanList.size()-1;
    }

    // inspect the scale pivot translation
    if (_GatherAnimChannel(TRANSLATE, iTrans, "scalePivotTranslate", "X", "Y", "Z", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // inspect the scale pivot point
    bool hasScalePivot = _GatherAnimChannel(TRANSLATE, iTrans, "scalePivot", "X", "Y", "Z", &mAnimChanList, writeAnim, true);
    if (hasScalePivot) {
        scalePivotIdx = mAnimChanList.size()-1;
    }

    // inspect the shear. Even if we have one xform on the xform list, it represents a share so we should name it
    if (_GatherAnimChannel(SHEAR, iTrans, "shear", "XY", "XZ", "YZ", &mAnimChanList, writeAnim, true)) {
        conformsToCommonAPI = false;
    }

    // add the scale. no suffix to be closer compatibility with common API
    _GatherAnimChannel(SCALE, iTrans, "scale", "X", "Y", "Z", &mAnimChanList, writeAnim, false);

    // inverse the scale pivot point
    if (hasScalePivot) {
        AnimChannel chan;
        chan.usdOpType = UsdGeomXformOp::TypeTranslate;
        chan.precision = UsdGeomXformOp::PrecisionFloat;
        chan.opName = "scalePivot";
        chan.isInverse = true;
        mAnimChanList.push_back(chan);
        scalePivotINVIdx = mAnimChanList.size()-1;
    }
    
    // If still potential common API, check if the pivots are the same and NOT animated/connected
    if (hasRotatePivot != hasScalePivot) {
        conformsToCommonAPI = false;
    }

    if (conformsToCommonAPI && hasRotatePivot && hasScalePivot) {
        AnimChannel rotPivChan, scalePivChan;
        rotPivChan = mAnimChanList[rotPivotIdx];
        scalePivChan = mAnimChanList[scalePivotIdx];
        // If they have different sampleType or are ANIMATED, does not conformsToCommonAPI anymore
        for (unsigned int i = 0;i<3;i++) {
            if (rotPivChan.sampleType[i] != scalePivChan.sampleType[i] ||
                    rotPivChan.sampleType[i] == ANIMATED) {
                conformsToCommonAPI = false;
            }
        }

        // If The defaultValue is not the same, does not conformsToCommonAPI anymore
        if (!GfIsClose(rotPivChan.defValue, scalePivChan.defValue, 1e-9)) {
            conformsToCommonAPI = false;
        }

        // If opType, usdType or precision are not the same, does not conformsToCommonAPI anymore
        if (rotPivChan.opType != scalePivChan.opType           || 
                rotPivChan.usdOpType != scalePivChan.usdOpType || 
                rotPivChan.precision != scalePivChan.precision) {
            conformsToCommonAPI = false;
        }

        if (conformsToCommonAPI) {
            // To Merge, we first rename rotatePivot and the scalePivot inverse
            // to pivot. Then we remove the scalePivot and the inverse of the
            // rotatePivot.
            //
            // This means that pivot and its inverse will wrap rotate and scale
            // since no other ops have been found
            //
            // NOTE: scalePivotIdx > rotPivotINVIdx
            mAnimChanList[rotPivotIdx].opName = "pivot";
            mAnimChanList[scalePivotINVIdx].opName = "pivot";
            mAnimChanList.erase(mAnimChanList.begin()+scalePivotIdx);
            mAnimChanList.erase(mAnimChanList.begin()+rotPivotINVIdx);
        }
    }
    
    // Loop over anim channel vector and create corresponding XFormOps
    // including the inverse ones if needed
    TF_FOR_ALL(iter, mAnimChanList) {
        AnimChannel& animChan = *iter;
        animChan.op = usdXformable.AddXformOp(
            animChan.usdOpType, animChan.precision,
            TfToken(animChan.opName),
            animChan.isInverse);
    }