Reading Alembic Vertex Cache Data using FBX SDK

Reading Alembic Vertex Cache Data using FBX SDK

ssontech
Contributor Contributor
1,424 Views
6 Replies
Message 1 of 7

Reading Alembic Vertex Cache Data using FBX SDK

ssontech
Contributor
Contributor

I'm trying to use the FBX SDK to pull vertex cache data out of Alembic files. (This is for a commercial product; it runs on normal FBX files.) The FBX SDK offers up an FbxVertexCacheDeformer and FbxCache, but the channel data isn't right. I see vertex cache deformer Channel.Get() is "/Object01/Box01/Box01Shape[P]" instead of the expected FbxVertexCacheDeformer::ePositions constant, ie "0".  FbxCache::GetChannelIndex works (returning 0), but GetChannelDataType fails, returning false. Similarly I get bad results from GetChannelSamplingRate, SampleCount, and PointCount.

 

My understanding is that the primary purpose of the Alembic part of the FBX SDK is to be able to read vertex cache data, so I'm pretty much expecting this to work. Is there a magic incantation required? Thanks


if (!pCache->OpenFileForRead())                              // OK
{
fprintf(logf, "*** Couldn't open the alembic cache for reading.\n");
errors++;
return;
};
lChannelIndex = pCache->GetChannelIndex(pVCD->Channel.Get());
if (lChannelIndex < 0)                   // returns zero
{
fprintf(logf, "*** Couldn't find the right alembic channel.\n");
errors++;
return;
};
pCache->GetChannelDataType(lChannelIndex, lChnlType);        // this call returns FALSE, leaving lChnlType uninitialized
if (lChnlType != FbxCache::eFloatVectorArray)
{
fprintf(logf, "*** Data isn't float vectors.\n");
errors++;
return;
};

0 Likes
1,425 Views
6 Replies
Replies (6)
Message 2 of 7

regalir
Autodesk
Autodesk

Hi,

first of all, not all the functions in the interface of the FbxCache apply to all the possible cache types. Some are in the Maya section and only apply to Maya caches. Calling them on the other supported caches format will not return any usable value. It is possible that, in a future release of the FBX SDK, we may be able to consolidate the FbxCache interface so more function could be called on all the supported cache formats.

 

This being said, the current interface is enough to retrieve the Alembic data and the code snippet below should demonstrate how to access it. Note that I wrote it from memory and it may need some tweaking but, hopefully, you'll get the idea 😉

 

 

FbxVertexCacheDeformer* deformer = FbxCast<FbxVertexCacheDeformer>(pFbxVertexCacheDeformer);
FbxMesh* mesh = pFbxVertexCacheDeformer->GetDstObject<FbxMesh>();
FbxCache* cache = deformer->GetCache();
switch( deformer->Type )
{
    case FbxVertexCacheDeformer::ePositions:	mVertexElement = Vertex::Element::Position; break;
    case FbxVertexCacheDeformer::eNormals:	mVertexElement = Vertex::Element::Normal; break;
    case FbxVertexCacheDeformer::eUVs:		mVertexElement = Vertex::Element::Texcoord0; break;
    case FbxVertexCacheDeformer::eTangents:	mVertexElement = Vertex::Element::Tangent; break;
    case FbxVertexCacheDeformer::eBinormals:	mVertexElement = Vertex::Element::Binormal; break;
    default:	break;
}

mChannelIndex = cache->GetChannelIndex(deformer->Channel.Get());

//If cache type is ePosition, then we know that it is always defined by control point.
However, for all the other types we have to look how the data is mapped in the mesh
(using the LayerElement::GetMappingMode()) so we can validate that we receive the corrent
amount.

mByControlPoint = ElementIsByControlPoint(mesh, mVertexElement);
if( deformer->Type.Get() != FbxVertexCacheDeformer::ePositions )
{
//First, if the mesh got triangulated, we cannot use this data since it won't match anymore
if( mesh->mOriginalControlPointsCount != 0 ) { deformer->Active = false; return; }

//Now verify that the cache channel read length is the size we are expecting
unsigned int Length = 0;
if( !cache->Read(nullptr, Length, FBXSDK_TIME_ZERO, mChannelIndex) )
{
mIsValid = false;
FBX_ASSERT_NOW("Unable to read from cache file!");
return;
}

if (mByControlPoint)
deformer->Active = (Length == mesh->GetControlPointsCount() * 3 );
else
deformer->Active = (Length == mesh->GetPolygonVertexCount() * 3 );

if (!deformer->Active) return;
}

unsigned int lSampleCount;
ret = cache->GetChannelSampleCount(mChannelIndex, lSampleCount, &lStatus);
if (ret && lSampleCount)
{
    FbxTime start, end, time, inc;
    ret = lCache->GetAnimationRange(lChannelIndex, start, end, &lStatus);
    inc = (end - start) / lSampleCount;
    for (time = start; time <= end; time += inc)
    {
     unsigned int bufferSize;
        float* buffer = NULL; // buffer belongs to 'cache' it is allocated internally so we don't need
// to free it ourselves. But we need to set/reset the pointer
        ret = cache->Read(&buffer, bufferSize, time, mChannelIndex);
    }
}

 

 

0 Likes
Message 3 of 7

sandnseapa
Explorer
Explorer

Thanks for the message. I'm already using the functions labeled "Format Independent Functions", though the GetChannelIndex function that you show and I use is in the Maya section. I call OpenFileForRead, which you do not... without it, even the GetChannelIndex function fails. Even with it, though, most of the format-independent Get....  functions fail or produce nil results. I can't get it to do anything useful. FBX Review doesn't read Alembic. There's no sample code, no sample files. I don't see that there's a way to proceed.     😞

 

 

 

0 Likes
Message 4 of 7

regalir
Autodesk
Autodesk

At this point, I must ask how you defined the alembic cache "in" the FBX file. For what I remember, Maya cannot export an alembic cache when you do "Create cache" (it only gives you the option to save mcc or mcx) therefore, I doubt you did export to the FBX file from Maya.

 

The FBX SDK can read abc files directly (limited to geometries and vertex caches) and the FbxScene with be polulated with the appropriate FbxMesh and FbxDeformer objects translated from Alembic (I assumed this is how you tried to read your ABC files).

 

For your information, FbxReview (v1.4.1.0) - desktop version - does read alembic files (both HDF5 and Ogawa flavors), as I just explained, by reading the ABC file directly. For the FBX SDK, please note that starting with version 2019.1, only the Ogawa flavor is supported. Also, be aware that we never provided support of Alembic cache on its WindowStore and IOs versions.

0 Likes
Message 5 of 7

sandnseapa
Explorer
Explorer

The file being read by FBX is an Alembic .abc Ogawa file containing animated vertex data, produced by a non-Autodesk application. The FBX SDK's overall emulation, where the .abc appears to be an FBX file, is generally working

 

The FBX Review I tested with is the one in the Windows Store. It's 1.4.1 --- I had no idea there was a separate but different version on Autodesk's site.... I'm pretty sure at one point the Windows Store version was the one folks were told to use, since I'd never be on the Windows Store otherwise 😉 I'll have to see what it does for comparison

0 Likes
Message 6 of 7

sandnseapa
Explorer
Explorer

My .abc file does read OK in FBX Review from Autodesk's site. That's good.... but bad because now I really don't know what incantation is required to make the vertex cache reading work! FWIW my reader uses FBX SDK 2018.1.1.

0 Likes
Message 7 of 7

regalir
Autodesk
Autodesk

Hi,

the code snipped I gave you is coming from the sources of FbxReview 🙂 but you can also look at the ViewScene sample. It can read abc files as well (although it only process the vertices channels mapped by control point).

 

I am also attaching one of my test file (I generated it with Maya a while ago) so you have a file that you know is working. As you may already be aware, finding public ABC files for testing is practically impossible. We did our best to implement the Alembic support but, despite our efforts, it is not impossible that some alembic files are not correctly understood by the the FBX SDK simply because we did not have access to similar definitions for thorough testing.

0 Likes