@@ -23,14 +23,15 @@ namespace adobe::usd {
2323
2424struct 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
3637bool
@@ -156,7 +157,7 @@ exportFbxTransform(ExportFbxContext& ctx, const Node& node, FbxNode* fbxNode)
156157void
157158setElementUVs (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