Fix exporting meshes with textures to obj.

This commit is contained in:
Leonardo Zide committed 2026-10-01 19:09:28 -07:00
1 parent 7b746acccf
commit f772eeaa92
2 files changed
+81 -45

No files matched your search

+27 -8
View File
@@ -386,18 +386,37 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
snprintf(Line, sizeof(Line), "usemtl %s\n", gColorList[DefaultColorIndex].SafeName);
else
snprintf(Line, sizeof(Line), "usemtl %s\n", gColorList[Section->ColorIndex].SafeName);
File.WriteLine(Line);
for (int Idx = 0; Idx < Section->DrawCount; Idx += 3)
if (Section->PrimitiveType == LC_MESH_TRIANGLES)
{
const long int idx1 = Indices[Idx + 0] + VertexOffset;
const long int idx2 = Indices[Idx + 1] + VertexOffset;
const long int idx3 = Indices[Idx + 2] + VertexOffset;
if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3)
for (int Idx = 0; Idx < Section->DrawCount; Idx += 3)
{
snprintf(Line, sizeof(Line), "f %ld//%ld %ld//%ld %ld//%ld\n", idx1, idx1, idx2, idx2, idx3, idx3);
File.WriteLine(Line);
const long int idx1 = Indices[Idx + 0] + VertexOffset;
const long int idx2 = Indices[Idx + 1] + VertexOffset;
const long int idx3 = Indices[Idx + 2] + VertexOffset;
if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3)
{
snprintf(Line, sizeof(Line), "f %ld//%ld %ld//%ld %ld//%ld\n", idx1, idx1, idx2, idx2, idx3, idx3);
File.WriteLine(Line);
}
}
}
else
{
for (int Idx = 0; Idx < Section->DrawCount; Idx += 3)
{
const long int idx1 = Indices[Idx + 0] + VertexOffset;
const long int idx2 = Indices[Idx + 1] + VertexOffset;
const long int idx3 = Indices[Idx + 2] + VertexOffset;
if (idx1 != idx2 && idx1 != idx3 && idx2 != idx3)
{
snprintf(Line, sizeof(Line), "f %ld//%ld//%ld %ld//%ld//%ld %ld//%ld//%ld\n", idx1 + mNumVertices, idx1, idx1 + mNumVertices, idx2 + mNumVertices, idx2, idx2 + mNumVertices, idx3 + mNumVertices, idx3, idx3 + mNumVertices);
File.WriteLine(Line);
}
}
}
}
+54 -37
View File
@@ -3227,8 +3227,6 @@ lcResult<void> Project::ExportWavefront(const QString& FileName)
if (!OBJFile.Open(QIODevice::WriteOnly))
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
quint32 vert = 1;
OBJFile.WriteLine("# Model exported from LeoCAD\n");
QFileInfo SaveInfo(SaveFileName);
@@ -3250,62 +3248,81 @@ lcResult<void> Project::ExportWavefront(const QString& FileName)
snprintf(Line, sizeof(Line), "newmtl %s\nKd %.2f %.2f %.2f\nD %.2f\n\n", Color.SafeName, Color.Value[0], Color.Value[1], Color.Value[2], Color.Value[3]);
else
snprintf(Line, sizeof(Line), "newmtl %s\nKd %.2f %.2f %.2f\n\n", Color.SafeName, Color.Value[0], Color.Value[1], Color.Value[2]);
MaterialFile.WriteLine(Line);
}
for (const lcModelPartsEntry& ModelPart : ModelParts)
auto WritePositions=[&Line, &OBJFile](const auto* Verts, int VertexCount, const lcMatrix44& ModelWorld)
{
lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh;
if (!Mesh)
continue;
const lcMatrix44& ModelWorld = ModelPart.WorldMatrix;
lcVertex* Verts = (lcVertex*)Mesh->mVertexData;
for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++)
for (int VertexIndex = 0; VertexIndex < VertexCount; VertexIndex++)
{
lcVector3 Vertex = lcMul31(Verts[VertexIdx].Position, ModelWorld);
snprintf(Line, sizeof(Line), "v %.2f %.2f %.2f\n", Vertex[0], Vertex[1], Vertex[2]);
lcVector3 Position = lcMul31(Verts[VertexIndex].Position, ModelWorld);
snprintf(Line, sizeof(Line), "v %.2f %.2f %.2f\n", Position[0], Position[1], Position[2]);
OBJFile.WriteLine(Line);
}
};
OBJFile.WriteLine("#\n\n");
}
for (const lcModelPartsEntry& ModelPart : ModelParts)
auto WriteNormals=[&Line, &OBJFile](const auto* Verts, int VertexCount, const lcMatrix44& ModelWorld)
{
lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh;
if (!Mesh)
continue;
const lcMatrix44& ModelWorld = ModelPart.WorldMatrix;
lcVertex* Verts = (lcVertex*)Mesh->mVertexData;
for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++)
for (int VertexIndex = 0; VertexIndex < VertexCount; VertexIndex++)
{
lcVector3 Normal = lcMul30(lcUnpackNormal(Verts[VertexIdx].Normal), ModelWorld);
lcVector3 Normal = lcMul30(lcUnpackNormal(Verts[VertexIndex].Normal), ModelWorld);
snprintf(Line, sizeof(Line), "vn %.2f %.2f %.2f\n", Normal[0], Normal[1], Normal[2]);
OBJFile.WriteLine(Line);
}
};
for (const lcModelPartsEntry& ModelPart : ModelParts)
{
lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh;
if (!Mesh)
continue;
const lcVertex* Verts = static_cast<const lcVertex*>(Mesh->mVertexData);
WritePositions(Verts, Mesh->mNumVertices, ModelPart.WorldMatrix);
const lcVertexTextured* VertsTextured = reinterpret_cast<const lcVertexTextured*>(Verts + Mesh->mNumVertices);
WritePositions(VertsTextured, Mesh->mNumTexturedVertices, ModelPart.WorldMatrix);
OBJFile.WriteLine("#\n\n");
}
int NumPieces = 0;
for (const lcModelPartsEntry& ModelPart : ModelParts)
{
snprintf(Line, sizeof(Line), "g Piece%.3d\n", NumPieces++);
OBJFile.WriteLine(Line);
lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh;
if (Mesh)
{
Mesh->ExportWavefrontIndices(OBJFile, ModelPart.ColorIndex, vert);
vert += Mesh->mNumVertices;
}
if (!Mesh)
continue;
const lcVertex* Verts = static_cast<const lcVertex*>(Mesh->mVertexData);
WriteNormals(Verts, Mesh->mNumVertices, ModelPart.WorldMatrix);
const lcVertexTextured* VertsTextured = reinterpret_cast<const lcVertexTextured*>(Verts + Mesh->mNumVertices);
WriteNormals(VertsTextured, Mesh->mNumTexturedVertices, ModelPart.WorldMatrix);
OBJFile.WriteLine("#\n\n");
}
int PieceCount = 0;
quint32 BaseVertex = 1;
for (const lcModelPartsEntry& ModelPart : ModelParts)
{
lcMesh* Mesh = !ModelPart.Mesh ? ModelPart.Info->GetMesh() : ModelPart.Mesh;
if (!Mesh)
continue;
snprintf(Line, sizeof(Line), "g Piece%.3d\n", PieceCount++);
OBJFile.WriteLine(Line);
Mesh->ExportWavefrontIndices(OBJFile, ModelPart.ColorIndex, BaseVertex);
BaseVertex += Mesh->mNumVertices + Mesh->mNumTexturedVertices;
}
return lcResult<void>();