Skip to content

Instantly share code, notes, and snippets.

@Mathias-Fuchs
Created October 13, 2021 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mathias-Fuchs/7f086086181eb84b73409c17900a1a91 to your computer and use it in GitHub Desktop.
Save Mathias-Fuchs/7f086086181eb84b73409c17900a1a91 to your computer and use it in GitHub Desktop.
the worker function that exports a Rhino mesh to INRIA mesh/meshb format, using the libmeshb7.h header
BOOL CMeshbExporterPlugIn::savemeshtomeshormeshb(const ON_Mesh& m, const wchar_t* filename) {
{
if (m.VertexCount() == 0) {
RhinoApp().Print("This mesh seems to be empty.");
return FALSE;
}
ON_Mesh* mdp = m.Duplicate();
if (!mdp) {
RhinoApp().Print("Could not duplicate the input mesh for some reason.");
return FALSE;
}
// apparently, the following function can not fail. If it doesn't find dup verts, mdp is still valid
// the meshb format has only face normals, not vertex normals and no texture coordinates, so we can simply ignore vertex normals
mdp->CombineIdenticalVertices(true, true);
if (!mdp || mdp->VertexCount() == 0) {
RhinoApp().Print("Could not duplicate the input mesh for some reason.");
return FALSE;
}
int nv = mdp->VertexCount();
std::wstring wfilename(filename);
std::string strfilename(wfilename.begin(), wfilename.end());
int64_t id = GmfOpenMesh(strfilename.c_str(), GmfWrite, 2, 3);
if (id == 0) {
ON_String err;
err.Format("Could not open file %d for writing.", filename);
return FALSE;
}
// only in human-readable mode, the precision works
// the following decision what file format to write is done a little casually but it is exactly the same way as meshb takes its decision
if (strstr(strfilename.c_str(), ".mesh") && !strstr(strfilename.c_str(), ".meshb")) {
if (mdp->HasDoublePrecisionVertices())
GmfSetFloatPrecision(id, 64);
else
GmfSetFloatPrecision(id, 32);
}
// Write the vertices
GmfSetKwd(id, GmfVertices, nv);
if (mdp->HasDoublePrecisionVertices())
for (const ON_3dPoint* v = mdp->m_dV.First(); v != mdp->m_dV.Last() + 1; v++)
GmfSetLin(id, GmfVertices, v->x, v->y, v->z, 0);
else
for (const ON_3fPoint* v = mdp->m_V.First(); v != mdp->m_V.Last() + 1; v++)
GmfSetLin(id, GmfVertices, v->x, v->y, v->z);
// Write the faces
int ntris = 0;
int nquads = 0;
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++) {
if (face->IsTriangle()) ntris++;
else if (face->IsQuad()) nquads++;
}
GmfSetKwd(id, GmfTriangles, ntris);
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsTriangle())
GmfSetLin(id, GmfTriangles, face->vi[0] + 1, face->vi[1] + 1, face->vi[2] + 1, 0);
GmfSetKwd(id, GmfQuadrilaterals, nquads);
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsQuad())
GmfSetLin(id, GmfQuadrilaterals, face->vi[0] + 1, face->vi[1] + 1, face->vi[2] + 1, face->vi[3] + 1, 0);
// write the normals in the same order
GmfSetKwd(id, GmfNormals, mdp->FaceCount());
ON_3dVector normal;
if (mdp->HasDoublePrecisionVertices()) {
const ON_3dPoint* const dV = mdp->m_dV.First();
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsTriangle() && face->ComputeFaceNormal(dV, normal))
GmfSetLin(id, GmfNormals, normal.x, normal.y, normal.z, 0);
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsQuad() && face->ComputeFaceNormal(dV, normal))
GmfSetLin(id, GmfNormals, normal.x, normal.y, normal.z, 0);
}
else {
const ON_3fPoint* const dV = mdp->m_V.First();
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsTriangle() && face->ComputeFaceNormal(dV, normal))
GmfSetLin(id, GmfNormals, (float)normal.x, (float)normal.y, (float)normal.z, 0);
for (const ON_MeshFace* face = mdp->m_F.First(); face != mdp->m_F.Last() + 1; face++)
if (face->IsQuad() && face->ComputeFaceNormal(dV, normal))
GmfSetLin(id, GmfNormals, (float)normal.x, (float)normal.y, (float)normal.z, 0);
}
GmfCloseMesh(id);
ON_String trimstr;
trimstr.Format("Wrote mesh with %i vertices, %i triangles, %i quads.\n", nv, ntris, nquads);
RhinoApp().Print(trimstr);
return TRUE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment