void
My_TestGLDrawing::OffscreenTest()
{
    DrawScene();
    WriteToFile("color", "color1_unselected.png");

    // select cube0
    _picker.Pick(GfVec2i(319,221), GfVec2i(320,222));
    DrawScene();
    WriteToFile("color", "color2_cube0_pickable.png");
    HdSelectionSharedPtr selection = _picker.GetSelection();
    HdSelection::HighlightMode mode = HdSelection::HighlightModeSelect;

    TF_VERIFY(selection->GetSelectedPrimPaths(mode).size() == 1);
    TF_VERIFY(selection->GetSelectedPrimPaths(mode)[0] == SdfPath("/cube0"));

    // make cube0 unpickable; it should not let us pick cube1 since it occludes
    SdfPathVector excludePaths = {SdfPath("/cube0")};
    _pickablesCol.SetExcludePaths(excludePaths);
    _picker.SetDoUnpickablesOcclude(true);
    _picker.Pick(GfVec2i(319,221), GfVec2i(320,222));
    DrawScene();
    WriteToFile("color", "color3_cube0_unpickable.png");
    selection = _picker.GetSelection();
    //TF_VERIFY(selection->GetSelectedPrimPaths(mode).size() == 0);
}
/* virtual */
void
Hdx_UnitTestWindow::OnPaintGL()
{
    //
    // Update the draw target's size and execute the unit test with
    // the draw target bound.
    //
    _drawTarget->Bind();
    _drawTarget->SetSize(GfVec2i(GetWidth(), GetHeight()));

    _unitTest->DrawTest();

    _drawTarget->Unbind();

    //
    // Blit the resulting color buffer to the window (this is a noop
    // if we're drawing offscreen).
    //
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, _drawTarget->GetFramebufferId());

    glBlitFramebuffer(0, 0, GetWidth(), GetHeight(),
                      0, 0, GetWidth(), GetHeight(),
                      GL_COLOR_BUFFER_BIT,
                      GL_NEAREST);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
Ejemplo n.º 3
0
void
Picker::Pick(GfVec2i const& startPos,
             GfVec2i const& endPos)
{
    if (!_intersector)
        return;

    // for readability
    GfVec2i const& pickRadius               = _pParams.pickRadius;
    float const& width                      = _pParams.screenWidth;
    float const& height                     = _pParams.screenHeight;
    GfFrustum const& frustum                = _pParams.viewFrustum;
    GfMatrix4d const& viewMatrix            = _pParams.viewMatrix;

    int fwidth  = std::max(pickRadius[0], std::abs(startPos[0] - endPos[0]));
    int fheight = std::max(pickRadius[1], std::abs(startPos[1] - endPos[1]));

    _intersector->SetResolution(GfVec2i(fwidth, fheight));
    
    GfVec2d min(2*startPos[0]/width-1, 1-2*startPos[1]/height);
    GfVec2d max(2*(endPos[0]+1)/width-1, 1-2*(endPos[1]+1)/height);
    // scale window
    GfVec2d origin = frustum.GetWindow().GetMin();
    GfVec2d scale = frustum.GetWindow().GetMax() - frustum.GetWindow().GetMin();
    min = origin + GfCompMult(scale, 0.5 * (GfVec2d(1.0, 1.0) + min));
    max = origin + GfCompMult(scale, 0.5 * (GfVec2d(1.0, 1.0) + max));
    
    GfFrustum pickFrustum(frustum);
    pickFrustum.SetWindow(GfRange2d(min, max));

    HdxIntersector::Params iParams;
    iParams.pickTarget         = _pParams.pickTarget;
    iParams.doUnpickablesOcclude = _pParams.doUnpickablesOcclude;
    iParams.hitMode          = HdxIntersector::HitFirst;
    iParams.projectionMatrix = pickFrustum.ComputeProjectionMatrix();
    iParams.viewMatrix       = viewMatrix;

    std::cout << "Pick " << startPos << " - " << endPos << "\n";

    HdxIntersector::Result result;
    _intersector->Query(iParams,
                        *_pParams.pickablesCol,
                        _pParams.engine, 
                        &result);

    HdxIntersector::HitSet hits;
    HdSelectionSharedPtr selection(new HdSelection);
    if (result.ResolveUnique(&hits)) {
        AggregatedHits aggrHits = _AggregateHits(hits);

        for(const auto& pair : aggrHits) {
            _ProcessHit(pair.second, _pParams.pickTarget, _pParams.highlightMode,
                        selection);
        }
    }

    _selectionTracker->SetSelection(selection);
}
void
Hdx_UnitTestWindow::OffscreenTest()
{
    _drawTarget->Bind();
    _drawTarget->SetSize(GfVec2i(GetWidth(), GetHeight()));

    _unitTest->OffscreenTest();

    _drawTarget->Unbind();
}
void
My_TestGLDrawing::MouseRelease(int button, int x, int y, int modKeys)
{
    Hdx_UnitTestGLDrawing::MouseRelease(button, x, y, modKeys);

    if (!(modKeys & GarchGLDebugWindow::Alt)) {
        _picker.Pick(_startPos, _endPos);
    }
    _startPos = _endPos = GfVec2i(0);
}
Ejemplo n.º 6
0
GlfSimpleLightingContext::GlfSimpleLightingContext() :
    _shadows(new GlfSimpleShadowArray(GfVec2i(1024, 1024), 0)),
    _worldToViewMatrix(1.0),
    _projectionMatrix(1.0),
    _sceneAmbient(0.01, 0.01, 0.01, 1.0),
    _useLighting(false),
    _useShadows(false),
    _useColorMaterialDiffuse(false),
    _lightingUniformBlockValid(false),
    _shadowUniformBlockValid(false),
    _materialUniformBlockValid(false)
{
}
void
My_TestGLDrawing::_SetPickParams()
{
    HdxUnitTestUtils::PickParams pParams;

    pParams.pickRadius     = GfVec2i(4,4);
    pParams.screenWidth    = GetWidth();
    pParams.screenHeight   = GetHeight();
    pParams.viewFrustum    = GetFrustum();
    pParams.viewMatrix     = GetViewMatrix();
    pParams.engine         = &_engine;
    pParams.pickablesCol   = &_pickablesCol;
    pParams.highlightMode  = HdSelection::HighlightModeSelect;
    // unpickable occlusion is false by default.
    _picker.SetPickParams(pParams);
}
/* virtual */
void
Hdx_UnitTestWindow::OnInitializeGL()
{
    GlfGlewInit();
    GlfRegisterDefaultDebugOutputMessageCallback();
    GlfContextCaps::InitInstance();

    std::cout << glGetString(GL_VENDOR) << "\n";
    std::cout << glGetString(GL_RENDERER) << "\n";
    std::cout << glGetString(GL_VERSION) << "\n";

    //
    // Create an offscreen draw target which is the same size as this
    // widget and initialize the unit test with the draw target bound.
    //
    _drawTarget = GlfDrawTarget::New(GfVec2i(GetWidth(), GetHeight()));
    _drawTarget->Bind();
    _drawTarget->AddAttachment("color", GL_RGBA, GL_FLOAT, GL_RGBA);
    _drawTarget->AddAttachment("depth", GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
                               GL_DEPTH24_STENCIL8);
    _unitTest->InitTest();

    _drawTarget->Unbind();
}
bool
HdxColorCorrectionTask::_CreateFramebufferResources(GLuint *texture)
{
    // If framebufferSize is not provided we use the viewport size.
    // This can be incorrect if the client/app has changed the viewport to
    // be different then the render window size. (E.g. UsdView CameraMask mode)
    GfVec2i fboSize = _framebufferSize;
    if (fboSize[0] <= 0 || fboSize[1] <= 0) {
        GLint res[4] = {0};
        glGetIntegerv(GL_VIEWPORT, res);
        fboSize = GfVec2i(res[2], res[3]);
    }

    bool createTexture = (_texture == 0 || fboSize != _textureSize);

    if (createTexture) {
        if (_texture != 0) {
            glDeleteTextures(1, &_texture);
            _texture = 0;
        }

        _textureSize = fboSize;

        GLint restoreTexture;
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &restoreTexture);

        glGenTextures(1, texture);
        glBindTexture(GL_TEXTURE_2D, *texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // XXX For step 1 we copy the client FBO texture, apply gamma to the
        // copy and write it back to the client texture.
        // A future step will likely create a 16F texture at the start of 
        // hydra rendering and use color-correction to render the results back
        // into the client FBO texture.

        // XXX For now we assume we always want R16F. We could perhaps expose
        //     this as client-API in HdxColorCorrectionTaskParams.
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, _textureSize[0], 
                     _textureSize[1], 0, GL_RGBA, GL_FLOAT, 0);

        glBindTexture(GL_TEXTURE_2D, restoreTexture);
    }

    bool switchedGLContext = !_owningContext || !_owningContext->IsCurrent();

    if (switchedGLContext) {
        // If we're rendering with a different context than the render pass
        // was created with, recreate the FBO because FB is not shared.
        // XXX we need this since we use a FBO in _CopyTexture(). Ideally we
        // use HdxCompositor to do the copy, but for that we need to know the
        // textureId currently bound to the default framebuffer. However
        // glGetFramebufferAttachmentParameteriv will return and error when
        // trying to query the texture name bound to GL_BACK_LEFT.
        if (_owningContext && _owningContext->IsValid()) {
            GlfGLContextScopeHolder contextHolder(_owningContext);
            glDeleteFramebuffers(1, &_framebuffer);
        }

        _owningContext = GlfGLContext::GetCurrentGLContext();
        if (!TF_VERIFY(_owningContext, "No valid GL context")) {
            return false;
        }

        if (_framebuffer == 0) {
            glGenFramebuffers(1, &_framebuffer);
        }
    }

    if (createTexture || switchedGLContext) {
        GLint restoreReadFB, restoreDrawFB;
        glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &restoreReadFB);
        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &restoreDrawFB);
        glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                               GL_TEXTURE_2D, _texture, 0);

        glBindFramebuffer(GL_READ_FRAMEBUFFER, restoreReadFB);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawFB);
    }

    GLF_POST_PENDING_GL_ERRORS();
    return true;
}
Ejemplo n.º 10
0
bool
HdxIntersector::Query(HdxIntersector::Params const& params,
                      HdRprimCollection const& col,
                      HdEngine* engine,
                      HdxIntersector::Result* result)
{
    TRACE_FUNCTION();

    // Make sure we're in a sane GL state before attempting anything.
    if (GlfHasLegacyGraphics()) {
        TF_RUNTIME_ERROR("framebuffer object not supported");
        return false;
    }
    GlfGLContextSharedPtr context = GlfGLContext::GetCurrentGLContext();
    if (!TF_VERIFY(context)) {
        TF_RUNTIME_ERROR("Invalid GL context");
        return false;
    }
    if (!_drawTarget) {
        // Initialize the shared draw target late to ensure there is a valid GL
        // context, which may not be the case at constructon time.
        _Init(GfVec2i(128,128));
    }

    GfVec2i size(_drawTarget->GetSize());
    GfVec4i viewport(0, 0, size[0], size[1]);

    if (!TF_VERIFY(_renderPass)) {
        return false;
    }
    _renderPass->SetRprimCollection(col);

    // Setup state based on incoming params.
    _renderPassState->SetAlphaThreshold(params.alphaThreshold);
    _renderPassState->SetClipPlanes(params.clipPlanes);
    _renderPassState->SetCullStyle(params.cullStyle);
    _renderPassState->SetCamera(params.viewMatrix, params.projectionMatrix, viewport);
    _renderPassState->SetLightingEnabled(false);

    // Use a separate drawTarget (framebuffer object) for each GL context
    // that uses this renderer, but the drawTargets share attachments/textures.
    GlfDrawTargetRefPtr drawTarget = GlfDrawTarget::New(size);

    // Clone attachments into this context. Note that this will do a
    // light-weight copy of the textures, it does not produce a full copy of the
    // underlying images.
    drawTarget->Bind();
    drawTarget->CloneAttachments(_drawTarget);

    //
    // Setup GL raster state
    //

    GLenum drawBuffers[3] = { GL_COLOR_ATTACHMENT0,
                              GL_COLOR_ATTACHMENT1,
                              GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, drawBuffers);
    
    glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
    glDisable(GL_BLEND);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);  

    glClearColor(0,0,0,0);
    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);

    GLF_POST_PENDING_GL_ERRORS();
    
    //
    // Execute the picking pass
    //
    {
        GLuint vao;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
        // Setup stencil state and prevent writes to color buffer.
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, 1, 1);
        glStencilOp(GL_KEEP,     // stencil failed
                    GL_KEEP,     // stencil passed, depth failed
                    GL_REPLACE); // stencil passed, depth passed

        //
        // Condition the stencil buffer.
        //
        params.depthMaskCallback();
        // we expect any GL state changes are restored.

        // Disable stencil updates and setup the stencil test.
        glStencilFunc(GL_LESS, 0, 1);
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        // Clear depth incase the depthMaskCallback pollutes the depth buffer.
        glClear(GL_DEPTH_BUFFER_BIT);
        // Restore color outputs & setup state for rendering
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glDisable(GL_CULL_FACE);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glFrontFace(GL_CCW);

        //
        // Enable conservative rasterization, if available.
        //
        // XXX: This wont work until it's in the Glew build.
        bool convRstr = glewIsSupported("GL_NV_conservative_raster");
        if (convRstr) {
            // XXX: this should come from Glew
            #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
            glEnable(GL_CONSERVATIVE_RASTERIZATION_NV);
        }

        // 
        // Execute
        //
        // XXX: make intersector a Task
        HdTaskSharedPtrVector tasks;
        tasks.push_back(boost::make_shared<HdxIntersector_DrawTask>(_renderPass,
                                                               _renderPassState,
                                                            params.renderTags));
        engine->Execute(*_index, tasks);

        glDisable(GL_STENCIL_TEST);

        if (convRstr) {
            // XXX: this should come from Glew
            #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
            glDisable(GL_CONSERVATIVE_RASTERIZATION_NV);
        }

        // Restore
        glBindVertexArray(0);
        glDeleteVertexArrays(1, &vao);
    }

    GLF_POST_PENDING_GL_ERRORS();

    //
    // Capture the result buffers to be resolved later.
    //
    size_t len = size[0] * size[1];
    std::unique_ptr<unsigned char[]> primId(new unsigned char[len*4]);
    std::unique_ptr<unsigned char[]> instanceId(new unsigned char[len*4]);
    std::unique_ptr<unsigned char[]> elementId(new unsigned char[len*4]);
    std::unique_ptr<float[]> depths(new float[len]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("primId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &primId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("instanceId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &instanceId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("elementId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &elementId[0]);

    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("depth")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
                    &depths[0]);

    glBindTexture(GL_TEXTURE_2D, 0);

    GLF_POST_PENDING_GL_ERRORS();

    if (result) {
        *result = HdxIntersector::Result(
            std::move(primId), std::move(instanceId), std::move(elementId),
            std::move(depths), _index, params, viewport);
    }

    drawTarget->Unbind();
    GLF_POST_PENDING_GL_ERRORS();

    return true;
}
Ejemplo n.º 11
0
const HdxIntersector::Hit * 
UsdMayaGLBatchRenderer::_GetHitInfo(
    M3dView& view,
    unsigned int pickResolution,
    bool singleSelection,
    const SdfPath& sharedId,
    const GfMatrix4d &localToWorldSpace)
{
    // Guard against user clicking in viewer before renderer is setup
    if( !_renderIndex )
        return NULL;

    // Selection only occurs once per display refresh, with all usd objects
    // simulataneously. If the selectQueue is not empty, that means that
    // a refresh has occurred, and we need to perform a new selection operation.
    
    if( !_selectQueue.empty() )
    {
        TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg(
            "____________ SELECTION STAGE START ______________ (singleSelect = %d)\n",
            singleSelection );

        GfMatrix4d viewMatrix;
        GfMatrix4d projectionMatrix;
        px_LegacyViewportUtils::GetViewSelectionMatrices(view,
                                                         &viewMatrix,
                                                         &projectionMatrix);

        // As Maya doesn't support batched selection, intersection testing is
        // actually performed in the first selection query that happens after a
        // render. This query occurs in the local space of SOME object, but
        // we need results in world space so that we have results for every
        // node available. worldToLocalSpace removes the local space we
        // happen to be in for the initial query.
        GfMatrix4d worldToLocalSpace(localToWorldSpace.GetInverse());

        _intersector->SetResolution(GfVec2i(pickResolution, pickResolution));
        
        HdxIntersector::Params qparams;
        qparams.viewMatrix = worldToLocalSpace * viewMatrix;
        qparams.projectionMatrix = projectionMatrix;
        qparams.alphaThreshold = 0.1;
        
        _selectResults.clear();

        for( const auto &renderSetIter : _selectQueue )
        {
            const RenderParams &renderParams = renderSetIter.second.first;
            const _SdfPathSet &renderPaths = renderSetIter.second.second;
            SdfPathVector roots(renderPaths.begin(), renderPaths.end());
            
            TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg(
                    "--- pickQueue, batch %zx, size %zu\n",
                    renderSetIter.first, renderPaths.size());
            
            TfToken colName = renderParams.geometryCol;
            HdRprimCollection rprims(colName, renderParams.drawRepr);
            rprims.SetRootPaths(roots);
            rprims.SetRenderTags(renderParams.renderTags);

            qparams.cullStyle = renderParams.cullStyle;
            qparams.renderTags = renderParams.renderTags;

            HdxIntersector::Result result;
            HdxIntersector::HitVector hits;

            glPushAttrib(GL_VIEWPORT_BIT |
                         GL_ENABLE_BIT |
                         GL_COLOR_BUFFER_BIT |
                         GL_DEPTH_BUFFER_BIT |
                         GL_STENCIL_BUFFER_BIT |
                         GL_TEXTURE_BIT |
                         GL_POLYGON_BIT);
            bool r = _intersector->Query(qparams, rprims, &_hdEngine, &result);
            glPopAttrib();
            if( !r ) {
                continue;
            }
            
            if( singleSelection )
            {
                hits.resize(1);
                if( !result.ResolveNearest(&hits.front()) )
                    continue;
            }
            else if( !result.ResolveAll(&hits) )
            {
                continue;
            }

            for (const HdxIntersector::Hit& hit : hits) {
                auto itIfExists =
                    _selectResults.insert(
                        std::pair<SdfPath, HdxIntersector::Hit>(hit.delegateId, hit));
                
                const bool &inserted = itIfExists.second;
                if( inserted )
                    continue;
                                
                HdxIntersector::Hit& existingHit = itIfExists.first->second;
                if( hit.ndcDepth < existingHit.ndcDepth )
                    existingHit = hit;
            }
        }
        
        if( singleSelection && _selectResults.size()>1 )
        {
            TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg(
                    "!!! multiple singleSel hits found: %zu\n",
                    _selectResults.size());
            
            auto minIt=_selectResults.begin();
            for( auto curIt=minIt; curIt!=_selectResults.end(); curIt++ )
            {
                const HdxIntersector::Hit& curHit = curIt->second;
                const HdxIntersector::Hit& minHit = minIt->second;
                if( curHit.ndcDepth < minHit.ndcDepth )
                    minIt = curIt;
            }
            
            if( minIt!=_selectResults.begin() )
                _selectResults.erase(_selectResults.begin(),minIt);
            minIt++;
            if( minIt!=_selectResults.end() )
                _selectResults.erase(minIt,_selectResults.end());
        }
        
        if( TfDebug::IsEnabled(PXRUSDMAYAGL_QUEUE_INFO) )
        {
            for ( const auto &selectPair : _selectResults)
            {
                const SdfPath& path = selectPair.first;
                const HdxIntersector::Hit& hit = selectPair.second;
                cout << "NEW HIT: " << path << endl;
                cout << "\tdelegateId: " << hit.delegateId << endl;
                cout << "\tobjectId: " << hit.objectId << endl;
                cout << "\tndcDepth: " << hit.ndcDepth << endl;
            }
        }
        
        // As we've cached the results in pickBatches, we
        // can clear out the selection queue.
        _selectQueue.clear();

        // Selection can happen after a refresh but before a draw call, so
        // clear out the render queue as well
        _renderQueue.clear();

        // If nothing was selected, the view does not refresh, but this
        // means _selectQueue will not get processed again even if the
        // user attempts another selection. We fix the renderer state by
        // scheduling another refresh when the view is next idle.
        
        if( _selectResults.empty() )
            view.scheduleRefresh();
        
        TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg(
            "^^^^^^^^^^^^ SELECTION STAGE FINISH ^^^^^^^^^^^^^\n");
    }
    
    return TfMapLookupPtr( _selectResults, sharedId );
}
Ejemplo n.º 12
0
bool
PxrUsdMayaWriteUtil::SetUsdAttr(
        const MPlug& attrPlug,
        const UsdAttribute& usdAttr,
        const UsdTimeCode& usdTime,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    if (!usdAttr || attrPlug.isNull()) {
        return false;
    }

    bool isAnimated = attrPlug.isDestination();
    if (usdTime.IsDefault() == isAnimated) {
        return true;
    }

    // We perform a similar set of type-infererence acrobatics here as we do up
    // above in GetUsdTypeName(). See the comments there for more detail on a
    // few type-related oddities.

    MObject attrObj(attrPlug.attribute());

    if (attrObj.hasFn(MFn::kEnumAttribute)) {
        MFnEnumAttribute enumAttrFn(attrObj);
        const short enumIndex = attrPlug.asShort();
        const TfToken enumToken(enumAttrFn.fieldName(enumIndex).asChar());
        return usdAttr.Set(enumToken, usdTime);
    }

    MFnNumericData::Type numericDataType;
    MFnData::Type typedDataType;
    MFnUnitAttribute::Type unitDataType;

    _GetMayaAttributeNumericTypedAndUnitDataTypes(attrPlug,
                                                  numericDataType,
                                                  typedDataType,
                                                  unitDataType);

    if (attrObj.hasFn(MFn::kMatrixAttribute)) {
        typedDataType = MFnData::kMatrix;
    }

    switch (typedDataType) {
        case MFnData::kString: {
            MFnStringData stringDataFn(attrPlug.asMObject());
            const std::string usdVal(stringDataFn.string().asChar());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kMatrix: {
            MFnMatrixData matrixDataFn(attrPlug.asMObject());
            const GfMatrix4d usdVal(matrixDataFn.matrix().matrix);
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kStringArray: {
            MFnStringArrayData stringArrayDataFn(attrPlug.asMObject());
            VtStringArray usdVal(stringArrayDataFn.length());
            for (unsigned int i = 0; i < stringArrayDataFn.length(); ++i) {
                usdVal[i] = std::string(stringArrayDataFn[i].asChar());
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kDoubleArray: {
            MFnDoubleArrayData doubleArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtFloatArray usdVal(doubleArrayDataFn.length());
                for (unsigned int i = 0; i < doubleArrayDataFn.length(); ++i) {
                    usdVal[i] = (float)doubleArrayDataFn[i];
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtDoubleArray usdVal(doubleArrayDataFn.length());
                for (unsigned int i = 0; i < doubleArrayDataFn.length(); ++i) {
                    usdVal[i] = doubleArrayDataFn[i];
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnData::kFloatArray: {
            MFnFloatArrayData floatArrayDataFn(attrPlug.asMObject());
            VtFloatArray usdVal(floatArrayDataFn.length());
            for (unsigned int i = 0; i < floatArrayDataFn.length(); ++i) {
                usdVal[i] = floatArrayDataFn[i];
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kIntArray: {
            MFnIntArrayData intArrayDataFn(attrPlug.asMObject());
            VtIntArray usdVal(intArrayDataFn.length());
            for (unsigned int i = 0; i < intArrayDataFn.length(); ++i) {
                usdVal[i] = intArrayDataFn[i];
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kPointArray: {
            MFnPointArrayData pointArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtVec3fArray usdVal(pointArrayDataFn.length());
                for (unsigned int i = 0; i < pointArrayDataFn.length(); ++i) {
                    MPoint tmpMayaVal = pointArrayDataFn[i];
                    if (tmpMayaVal.w != 0) {
                        tmpMayaVal.cartesianize();
                    }
                    usdVal[i] = GfVec3f((float)tmpMayaVal[0],
                                        (float)tmpMayaVal[1],
                                        (float)tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtVec3dArray usdVal(pointArrayDataFn.length());
                for (unsigned int i = 0; i < pointArrayDataFn.length(); ++i) {
                    MPoint tmpMayaVal = pointArrayDataFn[i];
                    if (tmpMayaVal.w != 0) {
                        tmpMayaVal.cartesianize();
                    }
                    usdVal[i] = GfVec3d(tmpMayaVal[0],
                                        tmpMayaVal[1],
                                        tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnData::kVectorArray: {
            MFnVectorArrayData vectorArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtVec3fArray usdVal(vectorArrayDataFn.length());
                for (unsigned int i = 0; i < vectorArrayDataFn.length(); ++i) {
                    MVector tmpMayaVal = vectorArrayDataFn[i];
                    usdVal[i] = GfVec3f((float)tmpMayaVal[0],
                                        (float)tmpMayaVal[1],
                                        (float)tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtVec3dArray usdVal(vectorArrayDataFn.length());
                for (unsigned int i = 0; i < vectorArrayDataFn.length(); ++i) {
                    MVector tmpMayaVal = vectorArrayDataFn[i];
                    usdVal[i] = GfVec3d(tmpMayaVal[0],
                                        tmpMayaVal[1],
                                        tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        default:
            break;
    }

    switch (numericDataType) {
        case MFnNumericData::kBoolean: {
            const bool usdVal(attrPlug.asBool());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kByte:
        case MFnNumericData::kChar: {
            const int usdVal(attrPlug.asChar());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kShort: {
            const int usdVal(attrPlug.asShort());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kInt: {
            const int usdVal(attrPlug.asInt());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::k2Short: {
            short tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k2Int: {
            int tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Short: {
            short tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::k3Int: {
            int tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::kFloat: {
            const float usdVal(attrPlug.asFloat());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::k2Float: {
            float tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2f(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Float: {
            float tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return _SetVec(usdAttr, GfVec3f(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::kDouble: {
            const double usdVal(attrPlug.asDouble());
            if (translateMayaDoubleToUsdSinglePrecision) {
                return usdAttr.Set((float)usdVal, usdTime);
            } else {
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnNumericData::k2Double: {
            double tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return usdAttr.Set(GfVec2f((float)tmp1, (float)tmp2), usdTime);
            } else {
                return usdAttr.Set(GfVec2d(tmp1, tmp2), usdTime);
            }
            break;
        }
        case MFnNumericData::k3Double: {
            double tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return _SetVec(usdAttr,
                               GfVec3f((float)tmp1,
                                       (float)tmp2,
                                       (float)tmp3),
                               usdTime);
            } else {
                return _SetVec(usdAttr, GfVec3d(tmp1, tmp2, tmp3), usdTime);
            }
            break;
        }
        case MFnNumericData::k4Double: {
            double tmp1, tmp2, tmp3, tmp4;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3, tmp4);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return _SetVec(usdAttr,
                               GfVec4f((float)tmp1,
                                       (float)tmp2,
                                       (float)tmp3,
                                       (float)tmp4),
                               usdTime);
            } else {
                return _SetVec(usdAttr,
                               GfVec4d(tmp1, tmp2, tmp3, tmp4),
                               usdTime);
            }
            break;
        }
        default:
            break;
    }

    switch (unitDataType) {
        case MFnUnitAttribute::kAngle:
        case MFnUnitAttribute::kDistance:
            if (translateMayaDoubleToUsdSinglePrecision) {
                const float usdVal(attrPlug.asFloat());
                return usdAttr.Set(usdVal, usdTime);
            } else {
                const double usdVal(attrPlug.asDouble());
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        default:
            break;
    }

    return false;
}
Ejemplo n.º 13
0
int
main(int argc, char *argv[])
{
    // GfVec2f
    {
        float vals[] = { 1.0f, 2.0f };
        GfVec2f v(vals);
        TF_AXIOM(v == GfVec2f(1,2));
        float const *f = v.GetArray();
        TF_AXIOM(f[0] == 1 and f[1] == 2);
    }

    // GfVec2i
    {
        int vals[] = { 1, 2 };
        GfVec2i v(vals);
        TF_AXIOM(v == GfVec2i(1,2));
        int const *i = v.GetArray();
        TF_AXIOM(i[0] == 1 and i[1] == 2);
        v.Set(0, 1);
        TF_AXIOM(v == GfVec2i(0,1));
    }

    // GfVec3i
    {
        int vals[] = { 1, 2, 3 };
        GfVec3i v(vals);
        TF_AXIOM(v == GfVec3i(1,2,3));
        int const *i = v.GetArray();
        TF_AXIOM(i[0] == 1 and i[1] == 2 and i[2] == 3);
        v.Set(0, 1, 2);
        TF_AXIOM(v == GfVec3i(0,1,2));
    }

    // GfVec4i
    {
        int vals[] = { 1, 2, 3, 4 };
        GfVec4i v(vals);
        TF_AXIOM(v == GfVec4i(1,2,3,4));
        int const *i = v.GetArray();
        TF_AXIOM(i[0] == 1 and i[1] == 2 and i[2] == 3 and i[3] == 4);
        v.Set(0, 1, 2, 3);
        TF_AXIOM(v == GfVec4i(0,1,2,3));
    }

    // GfVec3f
    {
        float vals[] = { 1.0f, 2.0f, 3.0f };
        GfVec3f v(vals);
        TF_AXIOM(v == GfVec3f(1,2,3));
        float const *f = v.GetArray();
        TF_AXIOM(f[0] == 1 and f[1] == 2 and f[2] == 3);
    }

    // GfVec4f
    {
        float vals[] = { 1.0f, 2.0f, 3.0f, 4.0f };
        GfVec4f v(vals);
        TF_AXIOM(v == GfVec4f(1,2,3,4));
        float const *f = v.GetArray();
        TF_AXIOM(f[0] == 1 and f[1] == 2 and f[2] == 3 and f[3] == 4);
    }

    // GfSize2, GfSize3
    {
        size_t vals[] = {1, 2, 3};
        TF_AXIOM(GfSize2(vals) == GfSize2(1,2));
        TF_AXIOM(GfSize3(vals) == GfSize3(1,2,3));
    }

    // GfMatrix2d
    {
        double vals[2][2] = {{1, 0},
                             {0, 1}};
        TF_AXIOM(GfMatrix2d(vals) == GfMatrix2d(1));
        GfMatrix2d m(vals);
        double const *d = m.GetArray();
        TF_AXIOM(d[0] == 1 and d[1] == 0 and
                 d[2] == 0 and d[3] == 1);
    }

    // GfMatrix2f
    {
        float vals[2][2] = {{1, 0},
                             {0, 1}};
        TF_AXIOM(GfMatrix2f(vals) == GfMatrix2f(1));
        GfMatrix2f m(vals);
        float const *f = m.GetArray();
        TF_AXIOM(f[0] == 1 and f[1] == 0 and
                 f[2] == 0 and f[3] == 1);
    }

    // GfMatrix3d
    {
        double vals[3][3] = {{1, 0, 0},
                             {0, 1, 0},
                             {0, 0, 1}};
        TF_AXIOM(GfMatrix3d(vals) == GfMatrix3d(1));
        GfMatrix3d m(vals);
        double const *d = m.GetArray();
        TF_AXIOM(d[0] == 1 and d[1] == 0 and d[2] == 0 and
                 d[3] == 0 and d[4] == 1 and d[5] == 0 and
                 d[6] == 0 and d[7] == 0 and d[8] == 1);
    }

    // GfMatrix4d
    {
        double vals[4][4] = {{1, 0, 0, 0},
                             {0, 1, 0, 0},
                             {0, 0, 1, 0},
                             {0, 0, 0, 1}};
        TF_AXIOM(GfMatrix4d(vals) == GfMatrix4d(1));
        GfMatrix4d m(vals);
        double const *d = m.GetArray();
        TF_AXIOM(d[ 0] == 1 and d[ 1] == 0 and d[ 2] == 0 and d[ 3] == 0 and
                 d[ 4] == 0 and d[ 5] == 1 and d[ 6] == 0 and d[ 7] == 0 and
                 d[ 8] == 0 and d[ 9] == 0 and d[10] == 1 and d[11] == 0 and
                 d[12] == 0 and d[13] == 0 and d[14] == 0 and d[15] == 1);
    }
    
    // half
    {
        float halfPosInf = half::posInf();
        TF_AXIOM(not std::isfinite(halfPosInf));
        TF_AXIOM(std::isinf(halfPosInf));

        float halfNegInf = half::negInf();
        TF_AXIOM(not std::isfinite(halfNegInf));
        TF_AXIOM(std::isinf(halfNegInf));

        float halfqNan = half::qNan();
        TF_AXIOM(std::isnan(halfqNan));

        float halfsNan = half::sNan();
        TF_AXIOM(std::isnan(halfsNan));
    }
    
    return 0;
}
Ejemplo n.º 14
0
SdfPath
My_TestGLDrawing::PickScene(int pickX, int pickY,
        int * outInstanceIndex,
        int * outElementIndex)
{
    int width = 128;
    int height = 128;

    GlfDrawTargetRefPtr drawTarget = GlfDrawTarget::New(GfVec2i(width, height));
    drawTarget->Bind();
    drawTarget->AddAttachment(
        "primId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
    drawTarget->AddAttachment(
        "instanceId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
    drawTarget->AddAttachment(
        "elementId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
    drawTarget->AddAttachment(
        "depth", GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
    drawTarget->Unbind();

    drawTarget->Bind();

    GLenum drawBuffers[] = { 
        GL_COLOR_ATTACHMENT0,
        GL_COLOR_ATTACHMENT1,
        GL_COLOR_ATTACHMENT2
    };
    glDrawBuffers(3, drawBuffers);

    glEnable(GL_DEPTH_TEST);

    GLfloat clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
    glClearBufferfv(GL_COLOR, 0, clearColor);
    glClearBufferfv(GL_COLOR, 1, clearColor);

    GLfloat clearDepth[1] = { 1.0f };
    glClearBufferfv(GL_DEPTH, 0, clearDepth);

    PickParam pickParam;
    pickParam.location = GfVec2d(pickX, pickY);
    pickParam.viewport = GfVec4d(0, 0, width, height);

    DrawScene(&pickParam);

    drawTarget->Unbind();

    GLubyte primId[width*height*4];
    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("primId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, primId);

    GLubyte instanceId[width*height*4];
    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("instanceId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, instanceId);

    GLubyte elementId[width*height*4];
    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("elementId")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, elementId);

    GLfloat depths[width*height];
    glBindTexture(GL_TEXTURE_2D,
        drawTarget->GetAttachments().at("depth")->GetGlTextureName());
    glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, depths);

    double zMin = 1.0;
    int zMinIndex = -1;
    for (int y=0, i=0; y<height; y++) {
        for (int x=0; x<width; x++, i++) {
            if (depths[i] < zMin) {
                    zMin = depths[i];
                    zMinIndex = i;
            }
        }
    }

    bool didHit = (zMin < 1.0);

    SdfPath result;
    if (didHit) {
        int idIndex = zMinIndex*4;

        result = _delegate->GetRenderIndex().GetRprimPathFromPrimId(
                HdxRenderSetupTask::DecodeIDRenderColor(&primId[idIndex]));
        if (outInstanceIndex) {
            *outInstanceIndex = HdxRenderSetupTask::DecodeIDRenderColor(
                    &instanceId[idIndex]);
        }
        if (outElementIndex) {
            *outElementIndex = HdxRenderSetupTask::DecodeIDRenderColor(
                    &elementId[idIndex]);
        }
    }

    return result;
}
Ejemplo n.º 15
0
bool
PxrUsdMayaWriteUtil::SetUsdAttr(
    const MPlug &plg,
    const UsdAttribute& usdAttr,
    const UsdTimeCode &usdTime)
{
    MStatus status;
    if (!usdAttr || plg.isNull() ) {
        return false;
    }

    bool isAnimated = plg.isDestination();
    if (usdTime.IsDefault() == isAnimated ) {
        return true;
    }

    // Set UsdAttr
    MObject attrObj = plg.attribute();
    if (attrObj.hasFn(MFn::kNumericAttribute)) {
        MFnNumericAttribute attrNumericFn(attrObj);
        switch (attrNumericFn.unitType())
        {
        case MFnNumericData::kBoolean:
            usdAttr.Set(plg.asBool(), usdTime);
            break;
        case MFnNumericData::kByte:
        case MFnNumericData::kChar:
            usdAttr.Set((int)plg.asChar(), usdTime);
            break;
        case MFnNumericData::kShort:
            usdAttr.Set(int(plg.asShort()), usdTime);
            break;
        case MFnNumericData::kInt:
            usdAttr.Set(int(plg.asInt()), usdTime);
            break;
        //case MFnNumericData::kLong:
        //case MFnNumericData::kAddr:
        //    usdAttr.Set(plg.asInt(), usdTime);
        //    break;
        case MFnNumericData::kFloat:
            usdAttr.Set(plg.asFloat(), usdTime);
            break;
        case MFnNumericData::kDouble:
            usdAttr.Set(plg.asDouble(), usdTime);
            break;
        case MFnNumericData::k2Short:
        {
            short tmp1, tmp2;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2);
            usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k2Int:
        {
            int tmp1, tmp2;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2);
            usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        //case MFnNumericData::k2Long:
        case MFnNumericData::k3Short:
        {
            short tmp1, tmp2, tmp3;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2, tmp3);
            usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::k3Int:
        {
            int tmp1, tmp2, tmp3;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2, tmp3);
            usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        //case MFnNumericData::k3Long:
        case MFnNumericData::k2Float:
        {
            float tmp1, tmp2;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2);
            usdAttr.Set(GfVec2f(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Float:
        {
            float tmp1, tmp2, tmp3;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2, tmp3);
            _SetVec(usdAttr, GfVec3f(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::k2Double:
        {
            double tmp1, tmp2;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2);
            usdAttr.Set(GfVec2d(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Double:
        {
            double tmp1, tmp2, tmp3;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2, tmp3);
            _SetVec(usdAttr, GfVec3d(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::k4Double:
        {
            double tmp1, tmp2, tmp3, tmp4;
            MFnNumericData attrNumericDataFn(plg.asMObject());
            attrNumericDataFn.getData(tmp1, tmp2, tmp3, tmp4);
            _SetVec(usdAttr, GfVec4d(tmp1, tmp2, tmp3, tmp4), usdTime);
            break;
        }
        default:
            return false;
        }
    }
    else if (attrObj.hasFn(MFn::kTypedAttribute)) {
        MFnTypedAttribute attrTypedFn(attrObj);
        switch (attrTypedFn.attrType())
        {
        case MFnData::kString:
            usdAttr.Set(std::string(plg.asString().asChar()), usdTime);
            break;
        case MFnData::kMatrix:
        {
            MFnMatrixData attrMatrixDataFn(plg.asMObject());
            MMatrix mat1 = attrMatrixDataFn.matrix();
            usdAttr.Set(GfMatrix4d(mat1.matrix), usdTime);
            break;
        }
        case MFnData::kStringArray:
        {
            MFnStringArrayData attrDataFn(plg.asMObject());
            VtArray<std::string> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                usdVal[i] = std::string(attrDataFn[i].asChar());
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kIntArray:
        {
            MFnIntArrayData attrDataFn(plg.asMObject());
            VtArray<int> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                usdVal[i] = attrDataFn[i];
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kFloatArray:
        {
            MFnFloatArrayData attrDataFn(plg.asMObject());
            VtArray<float> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                usdVal[i] = attrDataFn[i];
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kDoubleArray:
        {
            MFnDoubleArrayData attrDataFn(plg.asMObject());
            VtArray<double> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                usdVal[i] = attrDataFn[i];
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kVectorArray:
        {
            MFnVectorArrayData attrDataFn(plg.asMObject());
            VtArray<GfVec3d> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                MVector tmpMayaVal = attrDataFn[i];
                usdVal[i] = GfVec3d(tmpMayaVal[0], tmpMayaVal[1], tmpMayaVal[2]);
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kPointArray:
        {
            MFnPointArrayData attrDataFn(plg.asMObject());
            VtArray<GfVec4d> usdVal(attrDataFn.length());
            for (unsigned int i=0; i < attrDataFn.length(); i++) {
                MPoint tmpMayaVal = attrDataFn[i];
                usdVal[i] = GfVec4d(tmpMayaVal[0], tmpMayaVal[1], tmpMayaVal[2], tmpMayaVal[3]);
            }
            usdAttr.Set(usdVal, usdTime);
            break;
        }
        default:
            return false;
        }
    }
    else if (attrObj.hasFn(MFn::kUnitAttribute)) {
        //MFnUnitAttribute attrUnitFn(attrObj);
        return false;
    }
    else if (attrObj.hasFn(MFn::kEnumAttribute)) {
        MFnEnumAttribute attrEnumFn(attrObj);
        short enumIndex = plg.asShort();
        TfToken enumToken( std::string(attrEnumFn.fieldName(enumIndex, &status).asChar()) );
        usdAttr.Set(enumToken, usdTime);
        return false;
    }

    return true;
}