Skip to content

Commit

Permalink
ovis: add loadMesh
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Jul 19, 2024
1 parent ae52320 commit ee51f4f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
17 changes: 17 additions & 0 deletions modules/ovis/include/opencv2/ovis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,23 @@ CV_EXPORTS_W void createGridMesh(const String& name, const Size2f& size, const S
*/
CV_EXPORTS_W void createTriangleMesh(const String& name, InputArray vertices, InputArray normals = noArray(), InputArray indices = noArray());

/**
* Loads a mesh from a known resource location.
*
* The file format is determined by the file extension. Supported formats are Ogre @c .mesh and everything that Assimp can load.
* @param meshname Name of the mesh file
* @param vertices vertex coordinates, each value contains 3 floats
* @param indices per-face list of vertices, each value contains 3 ints
* @param normals per-vertex normals, each value contains 3 floats
* @param colors per-vertex colors, each value contains 4 uchars
* @param texCoords per-vertex texture coordinates, each value contains 2 floats
*
* @see addResourceLocation()
*/
CV_EXPORTS_W void loadMesh(const String& meshname, OutputArray vertices, OutputArray indices,
OutputArray normals = noArray(), OutputArray colors = noArray(),
OutputArray texCoords = noArray());

/// @deprecated use setMaterialProperty
CV_EXPORTS_W void updateTexture(const String& name, InputArray image);
//! @}
Expand Down
72 changes: 72 additions & 0 deletions modules/ovis/src/ovis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1155,5 +1155,77 @@ void updateTexture(const String& name, InputArray image)
CV_Assert(tex);
_createTexture(name, image.getMat());
}

void loadMesh(const String& meshname, OutputArray vertices, OutputArray indices, OutputArray normals, OutputArray colors, OutputArray texCoords)
{
CV_Assert(_app);

auto mesh = MeshManager::getSingleton().load(meshname, RESOURCEGROUP_NAME);
auto smeshes = mesh->getSubMeshes();
CV_Assert(smeshes.size() == 1);

auto smesh = smeshes.front();

CV_Assert(smesh->operationType == RenderOperation::OT_TRIANGLE_LIST);

if (auto ibuf = smesh->indexData->indexBuffer)
{
auto idtype = ibuf->getType() == HardwareIndexBuffer::IT_16BIT ? CV_16S : CV_32S;
auto imat = Mat(smesh->indexData->indexCount, 3, idtype);
ibuf->readData(0, ibuf->getSizeInBytes(), imat.ptr());
imat.copyTo(indices);
}

auto vertexData = smesh->useSharedVertices ? mesh->sharedVertexData : smesh->vertexData;
DefaultHardwareBufferManagerBase swhbm;

// download all buffers to CPU for reorganization
auto tmpVertexData = vertexData->clone(true, &swhbm);
auto tgtDecl = swhbm.createVertexDeclaration();
tgtDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); // separate position buffer

bool has_normals = vertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL);
bool has_texcoords = vertexData->vertexDeclaration->findElementBySemantic(VES_TEXTURE_COORDINATES);
bool has_colors = vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE);
if (has_normals)
tgtDecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL); // separate normal buffer
if (has_texcoords)
tgtDecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); // separate texcoord buffer
if (has_colors)
tgtDecl->addElement(3, 0, VET_UBYTE4_NORM, VES_DIFFUSE); // separate color buffer

tmpVertexData->reorganiseBuffers(tgtDecl);

// copy data
auto vertmat = Mat(vertexData->vertexCount, 3, CV_32F);
auto posbuf = tmpVertexData->vertexBufferBinding->getBuffer(0);
posbuf->readData(0, posbuf->getSizeInBytes(), vertmat.ptr());
vertmat.copyTo(vertices);

if(has_normals && normals.needed())
{
auto normmat = Mat(vertexData->vertexCount, 3, CV_32F);
auto nbuf = tmpVertexData->vertexBufferBinding->getBuffer(1);
nbuf->readData(0, nbuf->getSizeInBytes(), normmat.ptr());
normmat.copyTo(normals);
}

if(has_texcoords && texCoords.needed())
{
auto texmat = Mat(vertexData->vertexCount, 2, CV_32F);
auto tbuf = tmpVertexData->vertexBufferBinding->getBuffer(2);
tbuf->readData(0, tbuf->getSizeInBytes(), texmat.ptr());
texmat.copyTo(texCoords);
}

if(has_colors && colors.needed())
{
auto colmat = Mat(vertexData->vertexCount, 4, CV_8U);
auto cbuf = tmpVertexData->vertexBufferBinding->getBuffer(3);
cbuf->readData(0, cbuf->getSizeInBytes(), colmat.ptr());
colmat.copyTo(colors);
}
}

}
}

0 comments on commit ee51f4f

Please sign in to comment.