MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ extract_single_mesh()

Kakshya::MeshData MayaFlux::IO::ModelReader::extract_single_mesh ( const void *  ai_mesh,
const void *  ai_scene,
std::string_view  mesh_name,
std::string_view  material_name 
) const
private

Definition at line 374 of file ModelReader.cpp.

379{
380 const auto* mesh = static_cast<const aiMesh*>(ai_mesh_ptr);
381
382 using V = Nodes::MeshVertex;
383
384 std::vector<V> verts;
385 verts.reserve(mesh->mNumVertices);
386
387 for (unsigned int v = 0; v < mesh->mNumVertices; ++v) {
388 V vert {};
389
390 vert.position = {
391 mesh->mVertices[v].x,
392 mesh->mVertices[v].y,
393 mesh->mVertices[v].z
394 };
395
396 if (mesh->HasNormals()) {
397 vert.normal = {
398 mesh->mNormals[v].x,
399 mesh->mNormals[v].y,
400 mesh->mNormals[v].z
401 };
402 } else {
403 vert.normal = { 0.0F, 1.0F, 0.0F };
404 }
405
406 if (mesh->HasTangentsAndBitangents()) {
407 vert.tangent = {
408 mesh->mTangents[v].x,
409 mesh->mTangents[v].y,
410 mesh->mTangents[v].z
411 };
412 } else {
413 vert.tangent = { 1.0F, 0.0F, 0.0F };
414 }
415
416 if (mesh->HasTextureCoords(0)) {
417 vert.uv = {
418 mesh->mTextureCoords[0][v].x,
419 mesh->mTextureCoords[0][v].y
420 };
421 } else {
422 vert.uv = { 0.0F, 0.0F };
423 }
424
425 if (mesh->HasVertexColors(0)) {
426 vert.color = {
427 mesh->mColors[0][v].r,
428 mesh->mColors[0][v].g,
429 mesh->mColors[0][v].b
430 };
431 } else {
432 vert.color = { 0.8F, 0.8F, 0.8F };
433 }
434
435 vert.weight = 0.0F;
436 verts.push_back(vert);
437 }
438
439 std::vector<uint32_t> indices;
440 indices.reserve(static_cast<size_t>(mesh->mNumFaces) * 3);
441
442 for (unsigned int f = 0; f < mesh->mNumFaces; ++f) {
443 const aiFace& face = mesh->mFaces[f];
444 if (face.mNumIndices != 3) {
445 continue;
446 }
447 indices.push_back(face.mIndices[0]);
448 indices.push_back(face.mIndices[1]);
449 indices.push_back(face.mIndices[2]);
450 }
451
452 if (verts.empty() || indices.empty()) {
453 set_error("Mesh has no usable geometry after extraction");
454 return {};
455 }
456
457 auto data = Kakshya::MeshData::empty();
458 Kakshya::MeshInsertion ins(data.vertex_variant, data.index_variant);
459 ins.insert_flat(
460 std::span<const uint8_t>(
461 reinterpret_cast<const uint8_t*>(verts.data()),
462 verts.size() * sizeof(V)),
463 std::span<const uint32_t>(indices),
465
466 auto access = ins.build();
467 if (!access) {
468 set_error("MeshInsertion::build() failed");
469 return {};
470 }
471 data.layout = access->layout;
472
473 Kakshya::MeshSubrange sub;
474 sub.index_start = 0;
475 sub.index_count = static_cast<uint32_t>(indices.size());
476 sub.vertex_offset = 0;
477 sub.name = std::string(mesh_name);
478 sub.material_name = std::string(material_name);
479
480 const auto* s = static_cast<const aiScene*>(ai_scene);
481
482 if (s->mNumMaterials > 0 && mesh->mMaterialIndex < s->mNumMaterials) {
483 aiString tex_path;
484 const aiMaterial* mat = s->mMaterials[mesh->mMaterialIndex];
485 if (mat->GetTexture(aiTextureType_DIFFUSE, 0, &tex_path) == AI_SUCCESS) {
486 sub.diffuse_path = std::filesystem::path(tex_path.C_Str()).generic_string();
487 sub.diffuse_embedded = (!sub.diffuse_path.empty()
488 && sub.diffuse_path[0] == '*');
489
491 "ModelReader: mesh '{}' diffuse={} embedded={}",
492 std::string(mesh_name),
493 sub.diffuse_path,
494 sub.diffuse_embedded);
495 }
496 }
497
498 Kakshya::RegionGroup rg("submeshes");
499 rg.add_region(sub.to_region());
500 data.submeshes = std::move(rg);
501
503 "ModelReader: extracted mesh '{}' mat='{}' — {} verts, {} indices",
504 mesh_name.empty() ? "<unnamed>" : mesh_name,
505 material_name.empty() ? "<none>" : material_name,
506 verts.size(), indices.size());
507
508 return data;
509}
#define MF_DEBUG(comp, ctx,...)
Range size
void set_error(std::string msg) const
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.
static MeshData empty()
Construct an empty MeshData with the canonical 60-byte mesh layout.
Definition MeshData.hpp:49
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)

References MayaFlux::Kakshya::RegionGroup::add_region(), MayaFlux::Kakshya::MeshInsertion::build(), MayaFlux::Kakshya::MeshSubrange::diffuse_embedded, MayaFlux::Kakshya::MeshSubrange::diffuse_path, MayaFlux::Kakshya::MeshData::empty(), MayaFlux::Journal::FileIO, MayaFlux::Kakshya::VertexLayout::for_meshes(), MayaFlux::Kakshya::MeshSubrange::index_count, MayaFlux::Kakshya::MeshSubrange::index_start, MayaFlux::Kakshya::MeshInsertion::insert_flat(), MayaFlux::Journal::IO, MayaFlux::Kakshya::MeshSubrange::material_name, MF_DEBUG, MayaFlux::Kakshya::MeshSubrange::name, MayaFlux::Nodes::MeshVertex::position, set_error(), MayaFlux::Kakshya::MeshSubrange::to_region(), MayaFlux::IO::V, and MayaFlux::Kakshya::MeshSubrange::vertex_offset.

Referenced by create_mesh_network(), and extract_meshes().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: