Created
October 13, 2021 18:28
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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