Skip to content

Commit 5bde4df

Browse files
author
Keith Blackstone
committed
version 1.0.5 update
1 parent a59d270 commit 5bde4df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+866
-497
lines changed

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ build-meta
4545

4646
# Generated documentation
4747
docs
48-
bin
49-
50-
# Test
5148
Testing
49+
bin
5250
test/__pycache__
5351
test/output
5452
test/assets/fbx/*.usd

changelog.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
v1.0.5 June 26th, 2024
2+
fbx:
3+
- import/export linear/srgb option
4+
- import animations for non-skeletal nodes
5+
gltf:
6+
- documentation added khronos latest extensions to readme
7+
obj:
8+
- group name and material index propagation
9+
- import/export linear/srgb option
10+
sbsar:
11+
- if $outputsize is voluntary un-exposed we must skip resolution variant creation
12+
- support all output values
13+
- delayed substance engine initialization
14+
- set default resolution using a global class prim in USD for materials
15+
utility:
16+
- static analysis cleanup
17+
- move info from comment to doc
18+
119
v1.0.4 May 31st, 2024
220
gltf:
321
- ability to open gltf file from within usd archive

fbx/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ displacement → phongSurface::DisplacementColor
9191
```
9292
The phong to PBR conversion follows https://docs.microsoft.com/en-us/azure/remote-rendering/reference/material-mapping. Keep in mind it is a lossy conversion.
9393
94+
* `fbxOriginalColorSpace`: USD uses linear colorspace, however, FBX colorspace could be either linear or sRGB.
95+
The user can set which one the data was in during import. If the data is in sRGB it will be converted to linear while in USD. Exporting will also consider the original color space. See Export -> outputColorSpace for details.
96+
97+
```
98+
UsdStageRefPtr stage = UsdStage::Open("cube.fbx:SDF_FORMAT_ARGS:fbxOriginalColorSpace=sRGB")
99+
```
100+
94101
**Export:**
95102
96103
* `embedImages` Embed images in the exported fbx file instead of as separate files. Default is `false`.
@@ -100,6 +107,25 @@ displacement → phongSurface::DisplacementColor
100107
SdfLayer::FileFormatArguments args = { {"embedImages", "true"} };
101108
stage->Export("cube.fbx", false, args);
102109
```
110+
* `outputColorSpace`: USD uses linear colorspace, however, the original FBX colorspace could be either linear or sRGB.
111+
If fbxOriginalColorSpace was set the fileformat plugin will use it when exporting unless outputColorSpace is specified.
112+
113+
Order or precendence on export (Note: the plugin assumes usd data is linear)
114+
1. If outputColorSpace=linear, the usd color data is exported as is.
115+
2. If outputColorSpace=sRGB, the usd color data is converted to sRGB on export
116+
3. If outputColorSpace is not set and fbxOriginalColorSpace is known, it will export the color data in the original format
117+
4. If outputColorSpace is not set and fbxOriginalColorSpace is not known, it will export the color data as is.
118+
119+
Example:
120+
```
121+
UsdStageRefPtr stage = UsdStage::Open("cube.fbx:SDF_FORMAT_ARGS:fbxOriginalColorSpace=sRGB")
122+
123+
# round trip the asset using the original colorspace
124+
stage.Export("round_trip_original_cube_srgb.fbx") // exported file will have sRGB colorspace
125+
126+
# round trip the asset overriding the original colorspace
127+
stage.Export("round_trip_original_cube_linear.fbx:SDF_FORMAT_ARGS:outputColorSpace=linear") // exported file will have linear colorspace
128+
```
103129
104130
## Debug codes
105131
* `FILE_FORMAT_FBX`: Common debug messages.

fbx/src/fbx.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ namespace adobe::usd {
3535

3636
struct ExportFbxOptions
3737
{
38-
bool embedImages;
38+
bool embedImages = false;
3939
std::string exportParentPath;
40+
PXR_NS::TfToken outputColorSpace;
4041
};
4142

4243
struct Fbx

fbx/src/fbxExport.cpp

Lines changed: 33 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ namespace adobe::usd {
2323

2424
struct ExportFbxContext
2525
{
26-
UsdData* usd;
27-
Fbx* fbx;
26+
UsdData* usd = nullptr;
27+
Fbx* fbx = nullptr;
2828
std::vector<FbxSurfaceMaterial*> materials;
2929
std::vector<FbxMesh*> meshes;
3030
std::vector<FbxCamera*> cameras;
3131
std::vector<FbxNode*> skeletons;
3232
std::string exportParentPath;
33-
bool hasYUp;
33+
bool hasYUp = true;
34+
bool convertColorSpaceToSRGB = false;
3435
};
3536

3637
bool
@@ -156,7 +157,7 @@ exportFbxTransform(ExportFbxContext& ctx, const Node& node, FbxNode* fbxNode)
156157
void
157158
setElementUVs(FbxMesh* fbxMesh,
158159
FbxGeometryElementUV* elementUvs,
159-
const Primvar<PXR_NS::GfVec2f>& uvs)
160+
const Primvar<GfVec2f>& uvs)
160161
{
161162
FbxGeometryElement::EMappingMode uvMapping;
162163
if (!exportFbxMapping(uvs.interpolation, uvMapping)) {
@@ -235,17 +236,17 @@ exportFbxMeshes(ExportFbxContext& ctx)
235236

236237
// Positions
237238
size_t k = 0;
238-
for (size_t i = 0; i < m.faces.size(); i++) {
239+
for (size_t j = 0; j < m.faces.size(); j++) {
239240
fbxMesh->BeginPolygon();
240-
for (int j = 0; j < m.faces[i]; j++) {
241+
for (int l = 0; l < m.faces[j]; l++) {
241242
fbxMesh->AddPolygon(m.indices[k++]);
242243
}
243244
fbxMesh->EndPolygon();
244245
}
245246
fbxMesh->InitControlPoints(m.points.size());
246-
for (size_t i = 0; i < m.points.size(); i++) {
247-
GfVec3f p = m.points[i];
248-
fbxMesh->SetControlPointAt(FbxVector4(p[0], p[1], p[2]), i);
247+
for (size_t j = 0; j < m.points.size(); j++) {
248+
GfVec3f p = m.points[j];
249+
fbxMesh->SetControlPointAt(FbxVector4(p[0], p[1], p[2]), j);
249250
}
250251

251252
// Normals
@@ -258,15 +259,15 @@ exportFbxMeshes(ExportFbxContext& ctx)
258259

259260
FbxGeometryElementNormal* elementNormal = fbxMesh->CreateElementNormal();
260261
elementNormal->SetMappingMode(normalMapping);
261-
for (size_t i = 0; i < m.normals.values.size(); i++) {
262-
GfVec3f n = m.normals.values[i];
262+
for (size_t j = 0; j < m.normals.values.size(); j++) {
263+
GfVec3f n = m.normals.values[j];
263264
FbxVector4 normal = FbxVector4(n[0], n[1], n[2]);
264265
elementNormal->GetDirectArray().Add(normal);
265266
}
266267
if (m.normals.indices.size()) {
267268
elementNormal->SetReferenceMode(FbxGeometryElement::EReferenceMode::eIndexToDirect);
268-
for (size_t i = 0; i < m.normals.indices.size(); i++) {
269-
elementNormal->GetIndexArray().Add(m.normals.indices[i]);
269+
for (size_t j = 0; j < m.normals.indices.size(); j++) {
270+
elementNormal->GetIndexArray().Add(m.normals.indices[j]);
270271
}
271272
} else {
272273
elementNormal->SetReferenceMode(FbxGeometryElement::EReferenceMode::eDirect);
@@ -289,6 +290,7 @@ exportFbxMeshes(ExportFbxContext& ctx)
289290
}
290291
}
291292

293+
// Colors and Opacities
292294
if (m.colors.size() || m.opacities.size()) {
293295
TfToken interpolation;
294296
VtIntArray indices;
@@ -323,91 +325,33 @@ exportFbxMeshes(ExportFbxContext& ctx)
323325
interpolation.GetText());
324326
}
325327

326-
// TODO: Maybe it's necessary to adjust data if indices differ
328+
// Convert colors to sRGB if needed
329+
if (ctx.convertColorSpaceToSRGB) {
330+
for (size_t j = 0; j < colorValues.size(); j++) {
331+
colorValues[j][0] = linearToSRGB(colorValues[j][0]);
332+
colorValues[j][1] = linearToSRGB(colorValues[j][1]);
333+
colorValues[j][2] = linearToSRGB(colorValues[j][2]);
334+
}
335+
}
336+
327337
FbxGeometryElementVertexColor* vertexColor = fbxMesh->CreateElementVertexColor();
328338
vertexColor->SetMappingMode(colorMapping);
329339
if (indices.size()) {
330340
vertexColor->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
331341
vertexColor->GetIndexArray().SetCount(indices.size());
332-
for (size_t i = 0; i < indices.size(); i++) {
333-
vertexColor->GetIndexArray().SetAt(i, indices[i]);
342+
for (size_t j = 0; j < indices.size(); j++) {
343+
vertexColor->GetIndexArray().SetAt(j, indices[j]);
334344
}
335345
} else {
336346
vertexColor->SetReferenceMode(FbxGeometryElement::eDirect);
337347
}
338348
vertexColor->GetDirectArray().SetCount(colorValues.size());
339-
for (size_t i = 0; i < colorValues.size(); i++) {
340-
GfVec3f c = colorValues[i];
341-
FbxDouble4 vector = FbxDouble4(c[0], c[1], c[2], opacityValues[i]);
342-
vertexColor->GetDirectArray().SetAt(i, vector);
349+
for (size_t j = 0; j < colorValues.size(); j++) {
350+
GfVec3f c = colorValues[j];
351+
FbxDouble4 vector = FbxDouble4(c[0], c[1], c[2], opacityValues[j]);
352+
vertexColor->GetDirectArray().SetAt(j, vector);
343353
}
344354
}
345-
346-
// Crease
347-
// TfToken interpolateBoundary;
348-
// if (meshSchema.GetInterpolateBoundaryAttr().Get(&interpolateBoundary, timeCode))
349-
// {
350-
// if (UsdGeomTokens->edgeOnly == interpolateBoundary)
351-
// fbxMesh->SetBoundaryRule(FbxMesh::EBoundaryRule::eCreaseEdge);
352-
// else if (UsdGeomTokens->edgeAndCorner == interpolateBoundary)
353-
// fbxMesh->SetBoundaryRule(FbxMesh::EBoundaryRule::eCreaseAll);
354-
// }
355-
356-
// VtArray<int> creaseIndices;
357-
// VtArray<float> creaseSharpnesses;
358-
// VtArray<int> creaseLengths;
359-
360-
// if (meshSchema.GetCreaseIndicesAttr().Get(&creaseIndices, timeCode) &&
361-
// meshSchema.GetCreaseSharpnessesAttr().Get(&creaseSharpnesses, timeCode) &&
362-
// meshSchema.GetCreaseLengthsAttr().Get(&creaseLengths, timeCode))
363-
// {
364-
// bool onValuePerEdge = creaseSharpnesses.size() == creaseLengths.size();
365-
// size_t loopIndex = 0;
366-
367-
// if (onValuePerEdge)
368-
// {
369-
// for (size_t i = 0; i < creaseLengths.size(); i++)
370-
// {
371-
// int edgetVertCount = creaseLengths[i];
372-
// float sharpness = creaseSharpnesses[i];
373-
374-
// for (int j = 0; j < edgetVertCount; j++)
375-
// {
376-
// int creaseIndex = creaseIndices[loopIndex];
377-
// fbxMesh->SetVertexCreaseInfo(creaseIndex, sharpness);
378-
// loopIndex++;
379-
// }
380-
// }
381-
// }
382-
// else
383-
// {
384-
// for (size_t i = 0; i < creaseLengths.size(); i++)
385-
// {
386-
// int edgetVertCount = creaseLengths[i];
387-
388-
// for (int j = 0; j < edgetVertCount; j++)
389-
// {
390-
// int creaseIndex = creaseIndices[loopIndex];
391-
// float sharpness = creaseSharpnesses[loopIndex];
392-
// fbxMesh->SetVertexCreaseInfo(creaseIndex, sharpness);
393-
// loopIndex++;
394-
// }
395-
// }
396-
// }
397-
// }
398-
399-
// Smoothing
400-
// TODO: Add smoothing information to FBX.
401-
// VtArray<int> cornderSharpnessIndexes;
402-
// VtArray<float> cornerSharpnes;
403-
404-
// if (!geomMesh.GetCornerIndicesAttr().Get(&cornderSharpnessIndexes, timeCode) ||
405-
// !geomMesh.GetCornerSharpnessesAttr().Get(&cornerSharpnes, timeCode))
406-
// return;
407-
408-
// auto pSmoothingGroup = fbxMesh->CreateElementSmoothing();
409-
// pSmoothingGroup->SetMappingMode(FbxLayerElement::EMappingMode::eByControlPoint);
410-
// pSmoothingGroup->SetReferenceMode(FbxLayerElement::EReferenceMode::eIndexToDirect);
411355
}
412356
return true;
413357
}
@@ -626,7 +570,7 @@ exportSkeletons(ExportFbxContext& ctx)
626570
skeletonNodesMap[joint] = fbxNode;
627571
fbxNodes[j] = fbxNode;
628572
// auto nodePath = prim.GetName().GetString() + jointPath;
629-
// context.AddNodePath(PXR_NS::SdfPath(nodePath), currentNode);
573+
// context.AddNodePath(SdfPath(nodePath), currentNode);
630574

631575
FbxSkeleton* fbxSkeleton = FbxSkeleton::Create(ctx.fbx->scene, "");
632576
fbxNode->AddNodeAttribute(fbxSkeleton);
@@ -637,7 +581,7 @@ exportSkeletons(ExportFbxContext& ctx)
637581
fbxSkeleton->SetSkeletonType(fbxsdk::FbxSkeleton::eLimbNode);
638582
}
639583

640-
PXR_NS::GfMatrix4d restTransform = skeleton.restTransforms[j];
584+
GfMatrix4d restTransform = skeleton.restTransforms[j];
641585
FbxAMatrix fbxMatrix = GetFBXMatrixFromUSD(restTransform);
642586
fbxNode->LclRotation = fbxMatrix.GetR();
643587
fbxNode->LclTranslation = fbxMatrix.GetT();
@@ -867,6 +811,7 @@ exportFbx(const ExportFbxOptions& options, UsdData& usd, Fbx& fbx)
867811
ctx.usd = &usd;
868812
ctx.fbx = &fbx;
869813
ctx.exportParentPath = options.exportParentPath;
814+
ctx.convertColorSpaceToSRGB = shouldConvertToSRGB(usd, options.outputColorSpace);
870815
exportFbxSettings(ctx);
871816
exportFbxMaterials(ctx);
872817
exportFbxCameras(ctx);

0 commit comments

Comments
 (0)