changeset 30:1a0e823283e4

Add simple converter for converting ASCII ply files into binary format.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 22 Nov 2019 09:49:06 +0200
parents 5c7f63fe5c19
children 6847715b46cd
files Makefile ply2bin.cpp
diffstat 2 files changed, 188 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Nov 22 09:28:23 2019 +0200
+++ b/Makefile	Fri Nov 22 09:49:06 2019 +0200
@@ -10,7 +10,7 @@
 
 CFLAGS += $(SDL2_CFLAGS) $(GL_CFLAGS)
 
-TARGETS = gldragon$(BINEXT)
+TARGETS = gldragon$(BINEXT) ply2bin$(BINEXT)
 
 all: $(TARGETS)
 
@@ -24,5 +24,8 @@
 gldragon$(BINEXT): gldragon.o dmmodel.o dmutil.o
 	$(CXX) -o $@ $+ $(LDFLAGS) $(SDL2_LIBS) $(GL_LIBS)
 
+ply2bin$(BINEXT): ply2bin.o dmmodel.o dmutil.o
+	$(CXX) -o $@ $+ $(LDFLAGS)
+
 clean:
 	$(RM) $(TARGETS) *.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ply2bin.cpp	Fri Nov 22 09:49:06 2019 +0200
@@ -0,0 +1,184 @@
+//
+// ply2bin - Convert ASCII PLY file to binary PLY
+// Programmed and designed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
+// (C) Copyright 2019 Tecnic Software productions (TNSP)
+//
+// See file "COPYING" for license information.
+//
+#include <SDL.h>
+#include "dmutil.h"
+#include "dmmodel.h"
+
+
+bool dmFWriteFloatLE(FILE *fh, const float val)
+{
+    float tmp = SDL_SwapFloatLE(val);
+    return fwrite(&tmp, sizeof(tmp), 1, fh) == 1;
+}
+
+
+bool dmFWriteU32LE(FILE *fh, const Uint32 val)
+{
+    Uint32 tmp = SDL_SwapLE32(val);
+    return fwrite(&tmp, sizeof(tmp), 1, fh) == 1;
+}
+
+
+bool dmFWriteU8(FILE *fh, const Uint8 val)
+{
+    return fwrite(&val, sizeof(val), 1, fh) == 1;
+}
+
+
+bool dmFWriteBINPLY(FILE *fh, const DMModel &model)
+{
+    bool writeNormals = model.normals.size() == (unsigned int) model.nvertices;
+
+    fprintf(fh,
+    "ply\n"
+    "format binary_little_endian 1.0\n"
+    "element vertex %d\n"
+    "property float x\n"
+    "property float y\n"
+    "property float z\n",
+    model.nvertices);
+
+    if (writeNormals)
+    {
+        fprintf(fh,
+        "property float nx\n"
+        "property float ny\n"
+        "property float nz\n"
+        );
+    }
+
+    fprintf(fh,
+    "element face %d\n"
+    "property list uchar uint vertex_indices\n"
+    "end_header\n",
+    model.nfaces);
+
+    for (int nvert = 0; nvert < model.nvertices; nvert++)
+    {
+        const DMVector3 &vert = model.vertices[nvert];
+
+        if (!dmFWriteFloatLE(fh, vert.x) ||
+            !dmFWriteFloatLE(fh, vert.y) ||
+            !dmFWriteFloatLE(fh, vert.z))
+                return false;
+
+        if (writeNormals)
+        {
+            const DMVector3 &vert = model.normals[nvert];
+            if (!dmFWriteFloatLE(fh, vert.x) ||
+                !dmFWriteFloatLE(fh, vert.y) ||
+                !dmFWriteFloatLE(fh, vert.z))
+                return false;
+        }
+    }
+
+    for (int nface = 0, offs = 0; nface < model.nfaces; nface++)
+    {
+        if (!dmFWriteU8(fh, 3))
+            return false;
+
+        for (int nvert = 0; nvert < 3; nvert++)
+        {
+            if (!dmFWriteU32LE(fh, model.faces[offs++]))
+                return false;
+        }
+    }
+
+    return true;
+}
+
+
+int main(int argc, char *argv[])
+{
+    bool
+        optShowHelp = false;
+    std::string optInputFilename, optOutputFilename;
+    FILE *outFile = NULL;
+    DMModel model;
+
+    // Check commandline argument for enabling shaders
+    for (int narg = 1; narg < argc; narg++)
+    {
+        char *arg = argv[narg];
+        if (arg[0] == '-')
+        {
+            char *opt = arg + 1;
+
+            if ((opt[0] == '-' && opt[1] == 'h' && opt[2] == 'e') ||
+                opt[0] == '?' || (opt[0] == '-' && opt[1] == '?'))
+            {
+                optShowHelp = true;
+                break;
+            }
+            else
+            if (opt[0] == '-')
+                opt++;
+
+            switch (opt[0])
+            {
+                default:
+                    printf("Unknown option '%s'.\n", opt);
+                    goto exit;
+            }
+        }
+        else
+        {
+            std::string tmp = std::string(arg);
+            if (tmp.empty())
+            {
+                printf("ERROR: Invalid empty filename.\n");
+                goto exit;
+            }
+
+            if (optInputFilename.empty())
+                optInputFilename = tmp;
+            else
+            if (optOutputFilename.empty())
+                optOutputFilename = tmp;
+            else
+            {
+                printf("ERROR: Too many filenames specified.\n");
+                goto exit;
+            }
+        }
+    }
+
+    if (optInputFilename.empty() || optOutputFilename.empty() || optShowHelp)
+    {
+        printf(
+            "ply2bin - Convert ASCII PLY file to binary format PLY\n"
+            "Usage: %s [options] <input.ply> <output.ply>\n"
+            "-?            Show this help\n"
+            "\n",
+            argv[0]
+            );
+
+        goto exit;
+    }
+
+    if (!model.loadFromPLY(optInputFilename))
+        goto exit;
+
+    if ((outFile = fopen(optOutputFilename.c_str(), "wb")) == NULL)
+    {
+        printf("ERROR: Could not create output file.\n");
+        goto exit;
+    }
+
+    printf("Writing output PLY ..\n");
+    if (!dmFWriteBINPLY(outFile, model))
+    {
+        printf("ERROR: Error writing output PLY file.\n");
+    }
+
+exit:
+    if (outFile != NULL)
+        fclose(outFile);
+
+    return 0;
+}