Skip to content

Commit fc1ccf5

Browse files
author
Keith Blackstone
committed
v1.0.7 updates
1 parent 5a3b1b9 commit fc1ccf5

30 files changed

+1075
-733
lines changed

changelog.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
v1.0.7 August 30th, 2024
2+
fbx:
3+
- improved error handling in readFbx
4+
- add light export support
5+
- always make opacity a single value for usd on import
6+
- mesh and node error checking
7+
- export non-skeletal node animations
8+
gltf:
9+
- add support for importing lights
10+
- update tinygltf version
11+
- glb export avoid assert when there is a missing image file
12+
obj:
13+
- handle tabs before mtl name, and support .tif extension
14+
- fix for converting with multiple materials
15+
ply:
16+
- add support to uint16 ply and allow gsplat without high-order shs
17+
sbsar
18+
- plugin add 8k resolution
19+
stl
20+
- calculate normals from geometry
21+
utility:
22+
- adjust interface material attributes to be closer to ASM
23+
- fanTriangulate now fails when we have a malformed file
24+
125
v1.0.6 July 31st, 2024
226
fbx:
327
- update FBXSDK to 2020.3.7

fbx/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
||||
2121
|Cameras |||
2222
||||
23+
|Lights |⚠️|⚠️|
24+
||||
2325
|Mesh positions |||
2426
|Mesh normals |||
2527
|Mesh uvs |||
@@ -50,6 +52,7 @@
5052
|FbxSurfaceLambert → UsdPreviewSurface|
5153
|Hardware material is not imported|
5254

55+
- Only point, directional, and spot lights are imported. Other light types are ignored.
5356

5457
**Export:**
5558

@@ -69,6 +72,8 @@ opacity → phongSurface::TransparentColor
6972
ior → Not been used.
7073
displacement → phongSurface::DisplacementColor
7174

75+
- Only point, directional, and spot lights are imported. Other light types are exported as point lights.
76+
7277
- **OBS: The image files used by the UsdPreviewShader node will be extracted from the USDZ file and saved as PNG files in the same folder as the generated fbx. If the source file is USD the files should also be copied from the USD folder into the FBX folder.**
7378

7479
## File Format Arguments

fbx/src/fbx.cpp

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,30 +120,46 @@ printFbx(Fbx& fbx)
120120
if (debugSkels) {
121121
if (attrType == FbxNodeAttribute::eMesh) {
122122
FbxMesh* fbxMesh = FbxCast<FbxMesh>(attribute);
123-
int deformerCount = fbxMesh->GetDeformerCount(FbxDeformer::eSkin);
124-
for (int i = 0; i < deformerCount; i++) {
125-
FbxSkin* skin =
126-
FbxCast<FbxSkin>(fbxMesh->GetDeformer(i, FbxDeformer::eSkin));
127-
msg += " skin [";
128-
for (int j = 0; j < skin->GetClusterCount(); j++) {
129-
FbxCluster* cluster = skin->GetCluster(j);
130-
FbxNode* link = cluster->GetLink();
131-
msg += " skel::" + std::string(link->GetName());
123+
if (fbxMesh != nullptr) {
124+
int deformerCount = fbxMesh->GetDeformerCount(FbxDeformer::eSkin);
125+
for (int j = 0; j < deformerCount; j++) {
126+
FbxSkin* skin =
127+
FbxCast<FbxSkin>(fbxMesh->GetDeformer(j, FbxDeformer::eSkin));
128+
if (skin != nullptr) {
129+
msg += " skin [";
130+
for (int k = 0; k < skin->GetClusterCount(); k++) {
131+
FbxCluster* cluster = skin->GetCluster(k);
132+
if (cluster != nullptr) {
133+
FbxNode* link = cluster->GetLink();
134+
if (link != nullptr) {
135+
msg += " skel::" + std::string(link->GetName());
136+
} else {
137+
TF_WARN("Cluster link is nullptr");
138+
}
139+
} else {
140+
TF_WARN("Failed to retrieve cluster from skin");
141+
}
142+
}
143+
msg += "]";
144+
} else {
145+
TF_WARN("Failed to cast Deformer to FbxSkin");
146+
}
132147
}
133-
msg += "]";
148+
} else {
149+
TF_WARN("Failed to cast FbxNodeAttribute to FbxMesh");
134150
}
135151
}
152+
if (i < nodeAttrCount - 1) {
153+
msg += ", ";
154+
}
136155
}
137-
if (i < nodeAttrCount - 1) {
138-
msg += ", ";
139-
}
140-
}
141-
msg += " }";
142-
TF_DEBUG_MSG(FILE_FORMAT_FBX, "%*s%s\n", indent, " ", msg.c_str());
156+
msg += " }";
157+
TF_DEBUG_MSG(FILE_FORMAT_FBX, "%*s%s\n", indent, " ", msg.c_str());
143158

144-
indent += indentSize;
145-
for (int i = 0; i < node->GetChildCount(); i++) {
146-
printNode(node->GetChild(i), indent);
159+
indent += indentSize;
160+
for (int j = 0; j < node->GetChildCount(); j++) {
161+
printNode(node->GetChild(j), indent);
162+
}
147163
}
148164
};
149165
printNode(fbx.scene->GetRootNode(), indentSize);
@@ -159,6 +175,10 @@ EmbedReadCBFunction(void* pUserData,
159175
const void* pFileBuffer,
160176
size_t pSizeInBytes)
161177
{
178+
if (!pUserData || !pFileName || !pFileBuffer || pSizeInBytes < 1) {
179+
return FbxCallback::State::eNotHandled;
180+
}
181+
162182
Fbx* fbx = reinterpret_cast<Fbx*>(pUserData);
163183
TF_DEBUG_MSG(FILE_FORMAT_FBX, "EmbedReadCBFunction: %s\n", pFileName);
164184

@@ -185,33 +205,49 @@ bool
185205
readFbx(Fbx& fbx, const std::string& filename, bool onlyMaterials)
186206
{
187207
GUARD(fbx.manager != nullptr, "Invalid fbx manager");
208+
188209
FbxImporter* importer = FbxImporter::Create(fbx.manager, IOSROOT);
189-
FbxIOSettings* ios = FbxIOSettings::Create(fbx.manager, IOSROOT);
190210
GUARD(importer != nullptr, "Invalid fbx importer");
191-
GUARD(ios != nullptr, "Invalid ios settings");
211+
212+
FbxIOSettings* ios = FbxIOSettings::Create(fbx.manager, IOSROOT);
213+
if (!ios) {
214+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Failed to create FbxIOSettings");
215+
importer->Destroy();
216+
return false;
217+
}
192218

193219
fbx.filename = filename;
194220
ios->SetBoolProp(IMP_FBX_MATERIAL, true);
195221
ios->SetBoolProp(IMP_FBX_TEXTURE, true);
196222
ios->SetBoolProp(IMP_FBX_ANIMATION, !onlyMaterials);
197223
ios->SetBoolProp(IMP_FBX_MODEL, !onlyMaterials);
198224
fbx.loadImages = onlyMaterials;
225+
199226
if (!importer->Initialize(filename.c_str(), -1, ios)) {
200227
FbxString error = importer->GetStatus().GetErrorString();
201228
TF_RUNTIME_ERROR(FILE_FORMAT_FBX,
202-
"Call to FbxExporter::Initialize() failed on opening file %s \n",
229+
"Call to FbxImporter::Initialize() failed on opening file %s \n",
203230
filename.c_str());
204231
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Error returned: %s\n\n", error.Buffer());
205232
importer->Destroy();
233+
ios->Destroy();
206234
return false;
207235
}
236+
208237
// let fbx own importer
209238
fbx.importer = importer;
210239

211240
// Create the read callback to handle loading embedded data (ie images)
212241
FbxEmbeddedFileCallback* readCallback =
213242
FbxEmbeddedFileCallback::Create(fbx.manager, "EmbeddedFileReadCallback");
214-
GUARD(readCallback != nullptr, "Invalid read callback");
243+
244+
if (!readCallback) {
245+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Failed to create FbxEmbeddedFileCallback");
246+
importer->Destroy();
247+
ios->Destroy();
248+
return false;
249+
}
250+
215251
readCallback->RegisterReadFunction(EmbedReadCBFunction, (void*)&fbx);
216252
importer->SetEmbeddedFileReadCallback(readCallback);
217253

@@ -221,10 +257,11 @@ readFbx(Fbx& fbx, const std::string& filename, bool onlyMaterials)
221257
TF_DEBUG_MSG(FILE_FORMAT_FBX, "FBX importer opened file %s \n", filename.c_str());
222258
if (!importer->Import(fbx.scene)) {
223259
FbxString error = importer->GetStatus().GetErrorString();
224-
TF_RUNTIME_ERROR("Call to FbxExporter::Import() failed.\n");
225-
TF_RUNTIME_ERROR("Error returned: %s\n\n", error.Buffer());
260+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Call to FbxImporter::Import() failed.\n");
261+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Error returned: %s\n\n", error.Buffer());
226262
return false;
227263
}
264+
228265
TF_DEBUG_MSG(FILE_FORMAT_FBX, "FBX read success \n");
229266
printFbx(fbx);
230267
return true;
@@ -237,6 +274,10 @@ EmbedWriteCBFunction(void* pUserData,
237274
const void** pFileBuffer,
238275
size_t* pSizeInBytes)
239276
{
277+
if (!pUserData || !pFileName || !pFileBuffer || !pSizeInBytes || *pSizeInBytes < 1) {
278+
return FbxCallback::State::eNotHandled;
279+
}
280+
240281
Fbx* fbx = reinterpret_cast<Fbx*>(pUserData);
241282
TF_DEBUG_MSG(FILE_FORMAT_FBX, "EmbedWriteCBFunction: %s\n", pFileName);
242283
for (const ImageAsset& image : fbx->images) {
@@ -262,7 +303,11 @@ writeFbx(const ExportFbxOptions& options, const Fbx& fbx, const std::string& fil
262303
FbxIOSettings* ios = FbxIOSettings::Create(fbx.manager, IOSROOT);
263304

264305
GUARD(exporter != nullptr, "Invalid fbx exporter");
265-
GUARD(ios != nullptr, "Invalid ios settings");
306+
if (!ios) {
307+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Failed to create FbxIOSettings");
308+
exporter->Destroy();
309+
return false;
310+
}
266311
ios->SetBoolProp(EXP_FBX_MATERIAL, true);
267312
ios->SetBoolProp(EXP_FBX_TEXTURE, true);
268313
ios->SetBoolProp(EXP_FBX_ANIMATION, true);
@@ -296,10 +341,16 @@ writeFbx(const ExportFbxOptions& options, const Fbx& fbx, const std::string& fil
296341
writeCallback->RegisterWriteFunction(EmbedWriteCBFunction, (void*)&fbx);
297342
exporter->SetEmbeddedFileWriteCallback(writeCallback);
298343
exportResult = exporter->Export(fbx.scene);
344+
if (!exportResult) {
345+
FbxString error = exporter->GetStatus().GetErrorString();
346+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Call to FbxExporter::Export() failed.\n");
347+
TF_RUNTIME_ERROR(FILE_FORMAT_FBX, "Error returned: %s\n\n", error.Buffer());
348+
}
299349
writeCallback->Destroy();
300350
}
301351

302352
exporter->Destroy();
353+
ios->Destroy();
303354
return exportResult;
304355
}
305356

0 commit comments

Comments
 (0)