From 6722d3fb00113ce2ca4359351b1133278de751ad Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 7 May 2022 16:24:46 -0400 Subject: [PATCH] add simple STL binary to ASCII converter (based on Wikipedia specs) --- cmake/Modules/Tools.cmake | 3 ++ doc/src/Tools.rst | 22 +++++++++ tools/Makefile | 5 +- tools/README | 1 + tools/stl_bin2txt.cpp | 99 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tools/stl_bin2txt.cpp diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index c3b0a0771d..d2758f1f24 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -3,6 +3,9 @@ if(BUILD_TOOLS) target_compile_definitions(binary2txt PRIVATE -DLAMMPS_${LAMMPS_SIZES}) install(TARGETS binary2txt DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(stl_bin2txt ${LAMMPS_TOOLS_DIR}/stl_bin2txt.cpp) + install(TARGETS stl_bin2txt DESTINATION ${CMAKE_INSTALL_BINDIR}) + include(CheckGeneratorSupport) if(CMAKE_GENERATOR_SUPPORT_FORTRAN) include(CheckLanguage) diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 558824a81b..6330925844 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -56,6 +56,7 @@ Pre-processing tools * :ref:`moltemplate ` * :ref:`msi2lmp ` * :ref:`polybond ` + * :ref:`stl_bin2txt ` Post-processing tools @@ -1017,6 +1018,27 @@ For more details please see the README.md file in that folder. ---------- +.. _stlconvert: + +stl_bin2txt tool +---------------- + +The file stl_bin2txt.cpp converts binary STL files - like they are frequently +offered for download on the web - into ASCII format STL files that LAMMPS +can read with the :doc:`create_atoms mesh ` or the +:doc:`fix smd/wall_surface` commands. The syntax for running the tool is + +.. code-block:: bash + + stl_bin2txt infile.stl outfile.stl + +which creates outfile.stl from infile.stl. This tool must be compiled +on a platform compatible with the byteordering that was used to create +the binary file. This usually is a so-called little endian hardware +(like x86). + +---------- + .. _swig: SWIG interface diff --git a/tools/Makefile b/tools/Makefile index cd3c5756ae..ca2acc4c40 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -5,7 +5,7 @@ # all: - $(MAKE) binary2txt chain micelle2d + $(MAKE) binary2txt chain micelle2d stl_bin2txt binary2txt: binary2txt.o g++ -g binary2txt.o -o binary2txt @@ -19,6 +19,9 @@ micelle2d: micelle2d.o thermo_extract: thermo_extract.o gcc -g thermo_extract.o -o thermo_extract +stl_bin2txt: stl_bin2txt.o + g++ -g stl_bin2txt.o -o stl_bin2txt + clean: rm binary2txt chain micelle2d rm thermo_extract diff --git a/tools/README b/tools/README index 22e50b55fe..f53197bd18 100644 --- a/tools/README +++ b/tools/README @@ -46,6 +46,7 @@ replica tool to reorder LAMMPS replica trajectories according to singularity Singularity container descriptions suitable for LAMMPS development smd convert Smooth Mach Dynamics triangles to VTK spin perform a cubic polynomial interpolation of a GNEB MEP +stl_bin2txt convert binary STL files to ASCII swig Interface file and demo scripts for SWIG wrappers for the LAMMPS C library interface valgrind suppression files for use with valgrind's memcheck tool vim add-ons to VIM editor for editing LAMMPS input scripts diff --git a/tools/stl_bin2txt.cpp b/tools/stl_bin2txt.cpp new file mode 100644 index 0000000000..0c042ec975 --- /dev/null +++ b/tools/stl_bin2txt.cpp @@ -0,0 +1,99 @@ +/* ----------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/ + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------ */ + +// Convert a binary STL file to ASCII format +// Contributing author: Axel Kohlmeyer, Temple U, akohlmey at gmail.com +// +// Specs of the format taken from: https://en.wikipedia.org/wiki/STL_(file_format) + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + FILE *in, *out; + char title[80]; + float normal[3], vert1[3], vert2[3], vert3[3]; + uint32_t ntriangles; + size_t count; + uint16_t attributes; + + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + in = fopen(argv[1], "rb"); + if (!in) { + printf("Error opening input file %s: %s\n", argv[1], strerror(errno)); + return 2; + } + out = fopen(argv[2], "w"); + if (!out) { + printf("Error opening output file %s: %s\n", argv[1], strerror(errno)); + return 3; + } + + /* read header */ + count = fread(title, sizeof(char), sizeof(title), in); + if (count != sizeof(title)) { + printf("Error reading binary STL header: %s\n", strerror(errno)); + return 4; + } + count = strlen(title); + if (count == 0) snprintf(title, 80, "STL object from file %s", argv[1]); + + /* read triangle count */ + count = fread(&ntriangles, sizeof(uint32_t), 1, in); + if (count != 1) { + printf("Error reading binary STL triangle count: %s\n", strerror(errno)); + return 5; + } + + /* write header */ + printf("Converting: %s with %u triangles\n", title, ntriangles); + fprintf(out, "solid %s\n", title); + + /* loop over triangles */ + for (uint32_t i = 0; i < ntriangles; ++i) { + count = fread(normal, sizeof(float), 3, in); + count += fread(vert1, sizeof(float), 3, in); + count += fread(vert2, sizeof(float), 3, in); + count += fread(vert3, sizeof(float), 3, in); + if (count != 12) { + printf("Error reading binary STL vertices: %s\n", strerror(errno)); + return 6; + } + count = fread(&attributes, sizeof(uint16_t), 1, in); + if (count != 1) { + printf("Error reading binary STL facet attributes: %s\n", strerror(errno)); + return 7; + } + fprintf(out, " facet normal %e %e %e\n", normal[0], normal[1], normal[2]); + fputs(" outer loop\n", out); + fprintf(out, " vertex %e %e %e\n", vert1[0], vert1[1], vert1[2]); + fprintf(out, " vertex %e %e %e\n", vert2[0], vert2[1], vert2[2]); + fprintf(out, " vertex %e %e %e\n", vert3[0], vert3[1], vert3[2]); + fputs(" endloop\n endfacet\n", out); + if (ferror(out)) { + printf("Error writing text STL facet: %s\n", strerror(errno)); + return 7; + } + } + fprintf(out, "endsolid %s\n", title); + fclose(in); + fclose(out); + return 0; +}