Skip to content

Commit bc89ce6

Browse files
committed
Correct and fix PLY Writer
1 parent e09503d commit bc89ce6

File tree

5 files changed

+84
-66
lines changed

5 files changed

+84
-66
lines changed

examples_tests/50A.LoaderFixes/main.cpp renamed to examples_tests/27A.LoaderFixes/main.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ int main()
4949
#ifdef NBL_USE_STL_LOADER
5050
auto meshes_bundle = am->getAsset("../../media/extrusionLogo_TEST_fixed.stl", lp);
5151
#else
52-
auto meshes_bundle = am->getAsset("../../media/ply/Industrial compressor.ply", lp);
52+
auto meshes_bundle = am->getAsset("../../media/ply/Industrial_compressor.ply", lp);
5353
#endif // NBL_USE_STL_LOADER
5454

5555
assert(!meshes_bundle.getContents().empty());
@@ -60,6 +60,16 @@ int main()
6060
auto& cpuBundleData = loadAndGetCpuMesh();
6161
core::smart_refctd_ptr<asset::ICPUMesh> cpuMesh = cpuBundleData.first;
6262
auto metadata = cpuBundleData.second->selfCast<const asset::CPLYMetadata>();
63+
64+
#ifdef NBL_USE_STL_LOADER
65+
//asset::IAssetWriter::SAssetWriteParams wp(cpuMesh.get());
66+
//device->getAssetManager()->writeAsset("TODO.stl", wp);
67+
#else
68+
asset::IAssetWriter::SAssetWriteParams wp(cpuMesh.get());
69+
device->getAssetManager()->writeAsset("IndustrialWriteTest.ply", wp);
70+
#endif // NBL_USE_STL_LOADER
71+
72+
6373

6474
/*
6575
For the testing puposes we can safely assume all meshbuffers within mesh loaded from PLY & STL has same DS1 layout (used for camera-specific data)

examples_tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ add_subdirectory(23.Autoexposure EXCLUDE_FROM_ALL)
3636
#add_subdirectory(24.BufferSubDataAlignTest EXCLUDE_FROM_ALL) # TODO: @Anastazluk or @Hazardu
3737
#add_subdirectory(25.Blur EXCLUDE_FROM_ALL)
3838
add_subdirectory(26.MultidrawIndirectVSCPUCull EXCLUDE_FROM_ALL)
39+
add_subdirectory(27A.LoaderFixes EXCLUDE_FROM_ALL)
3940
#add_subdirectory(27.PointCloud EXCLUDE_FROM_ALL)
4041
if (NBL_BUILD_MITSUBA_LOADER AND NBL_BUILD_OPTIX)
4142
#add_subdirectory(28.OptiXPathTracing EXCLUDE_FROM_ALL)
@@ -61,4 +62,3 @@ add_subdirectory(45.BRDFEvalTest EXCLUDE_FROM_ALL)
6162
add_subdirectory(46.SamplingValidation EXCLUDE_FROM_ALL)
6263
add_subdirectory(47.DerivMapTest EXCLUDE_FROM_ALL)
6364
add_subdirectory(48.ArithmeticUnitTest EXCLUDE_FROM_ALL)
64-
add_subdirectory(50A.LoaderFixes EXCLUDE_FROM_ALL)

src/nbl/asset/interchange/CPLYMeshWriter.cpp

Lines changed: 72 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -85,37 +85,84 @@ bool CPLYMeshWriter::writeAsset(io::IWriteFile* _file, const SAssetWriteParams&
8585

8686
const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(ctx, mesh, 0u);
8787

88+
auto getConvertedMeshBufferWithNewIndexBuffer = [&]() -> core::smart_refctd_ptr<asset::ICPUMeshBuffer>
89+
{
90+
auto inputMeshBuffer = *meshbuffers.begin();
91+
92+
const auto inputIndexType = inputMeshBuffer->getIndexType();
93+
const auto inputPrimitiveType = inputMeshBuffer->getPipeline()->getPrimitiveAssemblyParams().primitiveType;
94+
95+
const void* inputIndices = inputMeshBuffer->getIndices();
96+
auto inputIndexCount = inputMeshBuffer->getIndexCount();
97+
98+
if (inputMeshBuffer->getIndexBufferBinding().buffer && inputPrimitiveType != asset::EPT_TRIANGLE_LIST)
99+
{
100+
auto copyMeshBuffer = core::smart_refctd_ptr_static_cast<asset::ICPUMeshBuffer>(inputMeshBuffer->clone());
101+
102+
if (inputPrimitiveType == asset::EPT_TRIANGLE_FAN || inputPrimitiveType == asset::EPT_TRIANGLE_STRIP)
103+
{
104+
core::smart_refctd_ptr<ICPUBuffer> newIndexBuffer;
105+
106+
if (inputPrimitiveType == asset::EPT_TRIANGLE_FAN)
107+
newIndexBuffer = IMeshManipulator::idxBufferFromTrianglesFanToTriangles(inputIndices, inputIndexCount, inputIndexType, inputIndexType);
108+
else if (inputPrimitiveType == asset::EPT_TRIANGLE_STRIP)
109+
newIndexBuffer = IMeshManipulator::idxBufferFromTriangleStripsToTriangles(inputIndices, inputIndexCount, inputIndexType, inputIndexType);
110+
111+
asset::SBufferBinding<asset::ICPUBuffer> indexBufferBinding;
112+
indexBufferBinding.buffer = newIndexBuffer;
113+
indexBufferBinding.offset = 0u;
114+
115+
copyMeshBuffer->setIndexBufferBinding(std::move(indexBufferBinding));
116+
return copyMeshBuffer;
117+
}
118+
}
119+
else
120+
return nullptr;
121+
};
122+
123+
const auto cpuConvertedMeshBuffer = getConvertedMeshBufferWithNewIndexBuffer();
124+
const asset::ICPUMeshBuffer* rawConvertedMeshBuffer = cpuConvertedMeshBuffer.get() ? cpuConvertedMeshBuffer.get() : *meshbuffers.begin();
125+
const auto primitiveType = rawConvertedMeshBuffer->getPipeline()->getPrimitiveAssemblyParams().primitiveType;
126+
const auto indexType = rawConvertedMeshBuffer->getIndexType();
127+
uint32_t faceCount = {};
128+
size_t vertexCount = {};
129+
130+
void* indices = nullptr;
131+
{
132+
auto indexCount = rawConvertedMeshBuffer->getIndexCount();
133+
134+
indices = _NBL_ALIGNED_MALLOC(indexCount * (indexType == asset::EIT_16BIT ? 2u : 4u), _NBL_SIMD_ALIGNMENT);
135+
memcpy(indices, rawConvertedMeshBuffer->getIndices(), indexCount * (indexType == asset::EIT_16BIT ? 2u : 4u));
136+
137+
IMeshManipulator::getPolyCount(faceCount, rawConvertedMeshBuffer);
138+
vertexCount = IMeshManipulator::upperBoundVertexID(rawConvertedMeshBuffer);
139+
}
140+
88141
// write PLY header
89142
std::string header = "ply\n";
90143
header += (flags & asset::EWF_BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0";
91144
header += "\ncomment IrrlichtBAW ";
92145
header += NABLA_SDK_VERSION;
93146

94-
auto meshBuffer = *meshbuffers.begin();
95-
// get vertex and triangle counts
96-
size_t vtxCount = IMeshManipulator::upperBoundVertexID(meshBuffer);
97-
size_t faceCount = meshBuffer->getIndexCount() / 3;
98-
99147
// vertex definition
100148
header += "\nelement vertex ";
101-
header += std::to_string(vtxCount) + '\n';
149+
header += std::to_string(vertexCount) + '\n';
102150

103151
bool vaidToWrite[4]{ 0, 0, 0, 0 };
104-
auto mbPipeline = meshBuffer->getPipeline();
105152

106-
if (meshBuffer->getAttribBoundBuffer(0).buffer)
153+
if (rawConvertedMeshBuffer->getAttribBoundBuffer(0).buffer)
107154
{
108-
const asset::E_FORMAT t = meshBuffer->getAttribFormat(0);
155+
const asset::E_FORMAT t = rawConvertedMeshBuffer->getAttribFormat(0);
109156
std::string typeStr = getTypeString(t);
110157
vaidToWrite[0] = true;
111158
header +=
112159
"property " + typeStr + " x\n" +
113160
"property " + typeStr + " y\n" +
114161
"property " + typeStr + " z\n";
115162
}
116-
if (meshBuffer->getAttribBoundBuffer(1).buffer)
163+
if (rawConvertedMeshBuffer->getAttribBoundBuffer(1).buffer)
117164
{
118-
const asset::E_FORMAT t = meshBuffer->getAttribFormat(1);
165+
const asset::E_FORMAT t = rawConvertedMeshBuffer->getAttribFormat(1);
119166
std::string typeStr = getTypeString(t);
120167
vaidToWrite[1] = true;
121168
header +=
@@ -127,100 +174,61 @@ bool CPLYMeshWriter::writeAsset(io::IWriteFile* _file, const SAssetWriteParams&
127174
header += "property " + typeStr + " alpha\n";
128175
}
129176
}
130-
if (meshBuffer->getAttribBoundBuffer(2).buffer)
177+
if (rawConvertedMeshBuffer->getAttribBoundBuffer(2).buffer)
131178
{
132-
const asset::E_FORMAT t = meshBuffer->getAttribFormat(2);
179+
const asset::E_FORMAT t = rawConvertedMeshBuffer->getAttribFormat(2);
133180
std::string typeStr = getTypeString(t);
134181
vaidToWrite[2] = true;
135182
header +=
136183
"property " + typeStr + " u\n" +
137184
"property " + typeStr + " v\n";
138185
}
139-
if (meshBuffer->getAttribBoundBuffer(3).buffer)
186+
if (rawConvertedMeshBuffer->getAttribBoundBuffer(3).buffer)
140187
{
141-
const asset::E_FORMAT t = meshBuffer->getAttribFormat(3);
188+
const asset::E_FORMAT t = rawConvertedMeshBuffer->getAttribFormat(3);
142189
std::string typeStr = getTypeString(t);
143190
vaidToWrite[3] = true;
144191
header +=
145192
"property " + typeStr + " nx\n" +
146193
"property " + typeStr + " ny\n" +
147194
"property " + typeStr + " nz\n";
148-
}
149-
150-
void* indices = nullptr;
151-
bool needToFreeIndices = false;
152-
153-
const void* ind = meshBuffer->getIndices();
154-
auto idxCnt = meshBuffer->getIndexCount(); // when you convert triangle Fan or triangle strip to triangle list, the index count changes, and thats what you should derive your face count from
155-
// github comment
156-
157-
const auto idxtype = meshBuffer->getIndexType();
158-
const auto primitiveT = mbPipeline->getPrimitiveAssemblyParams().primitiveType;
159-
160-
if (meshBuffer->getIndexBufferBinding().buffer && primitiveT != asset::EPT_TRIANGLE_LIST)
161-
{
162-
if (primitiveT == asset::EPT_TRIANGLE_FAN || primitiveT == asset::EPT_TRIANGLE_STRIP)
163-
{
164-
core::smart_refctd_ptr<ICPUBuffer> buf;
165-
if (primitiveT == asset::EPT_TRIANGLE_FAN)
166-
{
167-
buf = IMeshManipulator::idxBufferFromTrianglesFanToTriangles(ind, idxCnt, idxtype, idxtype);
168-
}
169-
else if (primitiveT == asset::EPT_TRIANGLE_STRIP)
170-
{
171-
buf = IMeshManipulator::idxBufferFromTriangleStripsToTriangles(ind, idxCnt, idxtype, idxtype);
172-
}
173-
needToFreeIndices = true;
174-
faceCount = buf->getSize() / (idxtype == asset::EIT_16BIT ? 2u : 4u) / 3u;
175-
indices = _NBL_ALIGNED_MALLOC(buf->getSize(),_NBL_SIMD_ALIGNMENT);
176-
memcpy(indices, buf->getPointer(), buf->getSize());
177-
}
178-
}
179-
else {
180-
indices = _NBL_ALIGNED_MALLOC(idxCnt * (idxtype == asset::EIT_16BIT ? 2u : 4u), _NBL_SIMD_ALIGNMENT);
181-
memcpy(indices, meshBuffer->getIndices(), idxCnt * (idxtype == asset::EIT_16BIT ? 2u : 4u));
182-
}
195+
}
183196

184197
asset::E_INDEX_TYPE idxT = asset::EIT_UNKNOWN;
185198
bool forceFaces = false;
186-
if (primitiveT == asset::EPT_POINT_LIST)
187-
{
199+
200+
if (primitiveType == asset::EPT_POINT_LIST)
188201
faceCount = 0u;
189-
}
190-
else if (indices && idxtype != asset::EIT_UNKNOWN)
202+
else if (indices && indexType != asset::EIT_UNKNOWN)
191203
{
192204
header += "element face ";
193205
header += std::to_string(faceCount) + '\n';
194-
idxT = idxtype;
206+
idxT = indexType;
195207
const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16";
196208
header += "property list uchar " + idxTypeStr + " vertex_indices\n";
197209
}
198-
else if (primitiveT == asset::EPT_TRIANGLE_LIST)
210+
else if (primitiveType == asset::EPT_TRIANGLE_LIST)
199211
{
200-
faceCount = vtxCount THIS IS ABSOLUTELY 100% WRONG / 3; // TODO: THIS IS WRONG
201212
forceFaces = true;
202213

203214
header += "element face ";
204215
header += std::to_string(faceCount) + '\n';
205-
idxT = vtxCount <= ((1u<<16) - 1) ? asset::EIT_16BIT : asset::EIT_32BIT;
216+
idxT = vertexCount <= ((1u<<16) - 1) ? asset::EIT_16BIT : asset::EIT_32BIT;
206217
const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16";
207218
header += "property list uchar " + idxTypeStr + " vertex_indices\n";
208219
}
209220
else
210-
{
211221
faceCount = 0u;
212-
}
213222
header += "end_header\n";
214223

215224
file->write(header.c_str(), header.size());
216225

217226
if (flags & asset::EWF_BINARY)
218-
writeBinary(file, meshBuffer, vtxCount, faceCount, idxT, indices, forceFaces, vaidToWrite, _params);
227+
writeBinary(file, rawConvertedMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, _params);
219228
else
220-
writeText(file, meshBuffer, vtxCount, faceCount, idxT, indices, forceFaces, vaidToWrite, _params);
229+
writeText(file, rawConvertedMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, _params);
221230

222-
if (needToFreeIndices)
223-
_NBL_ALIGNED_FREE(const_cast<void*>(indices));
231+
_NBL_ALIGNED_FREE(const_cast<void*>(indices));
224232

225233
return true;
226234
}

0 commit comments

Comments
 (0)