Hi again,
I have a problem in reading the normals info stored per Morph targets.
This is the code that I'm using, from the samples:
int lBlendShapeCount, lBlendShapeChannelCount, lTargetShapeCount; FbxBlendShape* lBlendShape; FbxBlendShapeChannel* lBlendShapeChannel; FbxShape* lShape; for (int lBlendShapeIndex = 0; lBlendShapeIndex < lBlendShapeCount; ++lBlendShapeIndex) { lBlendShape = (FbxBlendShape*)pMesh->GetDeformer(lBlendShapeIndex, FbxDeformer::eBlendShape); lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount(); for (int lBlendShapeChannelIndex = 0; lBlendShapeChannelIndex < lBlendShapeChannelCount; ++lBlendShapeChannelIndex) { lBlendShapeChannel = lBlendShape->GetBlendShapeChannel(lBlendShapeChannelIndex); lTargetShapeCount = lBlendShapeChannel->GetTargetShapeCount(); for (int lTargetShapeIndex = 0; lTargetShapeIndex < lTargetShapeCount; ++lTargetShapeIndex) { lShape = lBlendShapeChannel->GetTargetShape(lTargetShapeIndex); int j, lControlPointsCount = lShape->GetControlPointsCount(); FbxVector4* lControlPoints = lShape->GetControlPoints(); FbxLayerElementArrayTemplate<FbxVector4>* lNormals = NULL;
bool lStatus = lShape->GetNormals(&lNormals);
[...]
The problem is:
lStatus always returns true, but the values are all 0.0!
I check the ASCII version of my FBX file and there are non 0 values in the propriety "normals" of each shape!
Where is my error?
I've made some more tests using the original ImportScene sample from the FBX SDK package.
I'm using Visual Studio 2015 debugger to read the various values from vars during the execution:
Results are that
bool lStatus = lShape->GetNormals(&lNormals);
is always full of 0.0s...
but
If I check the values inside lNormals:
Under fbxsdk::FbxLayerElementArray this is what I find: (var name / value / type, separated by a tab)
- __vfptr 0x00cbc07c {ImportScene.exe!const fbxsdk::FbxLayerElementArrayTemplate<class fbxsdk::FbxVector4>::`vftable'} {...} void * * [0] 0x001c4b50 {ImportScene.exe!fbxsdk::FbxLayerElementArrayTemplate<class fbxsdk::FbxVector4>::`vector deleting destructor'(unsigned int)} void * [1] 0x001bc180 {ImportScene.exe!fbxsdk::FbxLayerElementArray::GetLocked(enum fbxsdk::FbxLayerElementArray::ELockMode,enum fbxsdk::EFbxType)} void * [2] 0x001bc3b0 {ImportScene.exe!fbxsdk::FbxLayerElementArray::Release(void * *,enum fbxsdk::EFbxType)} void * [3] 0x001bc610 {ImportScene.exe!fbxsdk::FbxLayerElementArray::GetStride(void)const } void * [4] 0x001bd610 {ImportScene.exe!fbxsdk::FbxLayerElementArray::ConvertDataType(enum fbxsdk::EFbxType,void * *,unsigned int *)} void * mDataType eFbxDouble4 (15) fbxsdk::EFbxType mStatus eSuccess (0) fbxsdk::LockAccessStatus::ELockAccessStatus mReadLockCount 0 int mWriteLock false bool mImplementation 0x01d3d808 void * mStride 32 unsigned int mDirectLockOn 0 int mDirectAccessOn false bool - mConvertedData {mSize=0 mCapacity=0 mArray=0x00000000 {???} } fbxsdk::FbxArray<void *> mSize 0 int mCapacity 0 int - mArray 0x00000000 {???} void * * <Unable to read memory> void *
mConvertedData-->mArray with question marks is what puzzles me more...
Any help is much appreciated.
Thanks!
Could at least someone confirm that this is not a BUG? Someone who correctly extracted shapes normal data from an FBX... thanks!
I am not able to load the file you posted. I won't load into Maya nor the ImportScene SDK example. Can you verify the FBX file?
That's strange. I just downloaded from the above link and open it in Maya 2015 without any problem.
The file was saved in Maya 2015, FBX plugin version 2015.1
File Version: 7.4.0
File Creator: FBX SDK/FBX Plugins version 2015.1
File Custom writer: No
File Creation Time: 2015/11/10 10:4:49
File Axis Direction: Y-up (RH)
File Units: Centimeters
System Axis Direction: Y-up
System Units: Centimeters
System frame rate: 30
File frame rate: 30
File content: 3 Elements, 18 Materials, 34 Textures
And I use FBX SDK version 2016.1.2 to load in my C++/CLI program.
The first download must have gotten corrupted. I tried again and it loaded properly. It's a huge number of triangles, perhaps in the future you can strip the file to bare minimum to make it easier to debug.
I confirm that the normals are are reading 0,0,0
Many thanks for your reply.
If you open that file in Maya and then save it in FBX ASCII, looking into the file using any text editor, you'll find normal values for each blend shape that are NOT (0, 0, 0) ...
(If you then use the FBX SDK on the ASCII version, it should return again normals as (0, 0, 0))
... that's why I'm supposing there should be a bug somewhere...
I could get legitmate normals from the blend shape, but not the target, if that helps.
FbxGeometry* geom = lBlendShape->GetGeometry(); int lControlPointsCount = geom->GetControlPointsCount(); for (int l = 0; l < geom->GetLayerCount(); l++) { FbxLayerElementNormal* pLayerNormals = geom->GetLayer(l)->GetNormals(); FbxLayerElement::EMappingMode normalMappingMode = pLayerNormals->GetMappingMode(); FbxLayerElement::EReferenceMode normalReferenceMode = pLayerNormals->GetReferenceMode(); switch (normalMappingMode) { case FbxLayerElement::eByControlPoint: { for (int controlPointIndex = 0; controlPointIndex < lControlPointsCount; controlPointIndex++) { FbxVector4 normal = pLayerNormals->GetDirectArray().GetAt(controlPointIndex); Display3DVector(" Normal Vector: ", normal); } break; } default: break; } }
Try this:
FbxGeometry* geom = lShape->GetBaseGeometry(); int lControlPointsCount = geom->GetControlPointsCount(); for (int l = 0; l < geom->GetLayerCount(); l++) { FbxLayerElementNormal* pLayerNormals = geom->GetLayer(l)->GetNormals(); FbxLayerElement::EMappingMode normalMappingMode = pLayerNormals->GetMappingMode(); FbxLayerElement::EReferenceMode normalReferenceMode = pLayerNormals->GetReferenceMode(); switch (normalMappingMode) { case FbxLayerElement::eByControlPoint: { for (int controlPointIndex = 0; controlPointIndex < lControlPointsCount; controlPointIndex++) { FbxVector4 normal = pLayerNormals->GetDirectArray().GetAt(controlPointIndex); Display3DVector(" Normal Vector: ", normal); } break; } default: break; } }
Documentation:
/** Get the base geometry of this target shape.
* \return a pointer to the base geometry if set or NULL.
* \remarks Since target shape can only connected to its base geometry through
* blend shape channel and blend shape deformer.
* So only when this target shape is connected to a blend shape channel,
* and the blend shape channel is connected to a blend shape deformer,
* and the blend shape deformer is used on a base geometry, then to get
* base geometry will success.
*/
That was one of my experiments... It returns the normals of the unmorphed base mesh, which is not exactly what I need.
I'm more oriented in recomputing the normals for each shape using some known alghoritm. But still I'm curious:
Are you a member of the beta FBX SDK area? I think there is a way to formal way to file issues there, also.
There is something else I found. In the FBX ascii file, there are 5269 control points, 15807 vertices and 15807 normals for the target shapes. From that data, I would think that the normals should be eByPolygonVertex and the count should be 15807, but the normal count from the SDK is 5269 and mapped as eByControlPoint.
As a possible workaround, can you change the way you are creating normals to actually be eByControlPoint in the FBX file?
I've noticed that mismatch too... But I was unsure if it could have been the issue or just misleading. The FBX is exported using maya plugin, I don't know how to modify it if the SDK is unable to read it correctly...
Hi kors,
I am logging this issue as FBXX-1048. I cannot acces the file you posted. Could you please send it to me directly, so that I can attach it to the logged issue?
viviane.rochon (at) autodesk.com
Thanks!
Can't find what you're looking for? Ask the community or share your knowledge.