commit fbaa63c434a5856441f1e26661cc28817055e966
parent 81f0a74f447c1dd168cd2acf4ab9c3589c72e758
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 29 Jun 2026 16:20:51 +0200
The input file is now an optional input argument.
As a result, the input data is not necessarily copied to a temporary
file, as was the case when data was read from standard input. This
should improve performance.
Note that the performance gains are not immediate, because data
processing can no longer assume that the data has been preprocessed by a
copy step that removes leading and trailing spaces and multiple spaces.
Regular expressions must therefore account for more scenarios, making
them more computationally intensive to evaluate.
However, it appears (at least with GNU grep) that basic regular
expressions (BREs) are evaluated less efficiently than extended regular
expressions (EREs). Thus, using EREs for grep directives minimizes the
performance loss associated with more complex regular expressions.
Providing a file as a command argument therefore results in a
significant performance gain without this new capability having too much
of an impact on the performance of the previous behavior.
Diffstat:
| M | obj2vtk | | | 52 | ++++++++++++++++++++++++++++++++++------------------ |
| M | obj2vtk.1 | | | 7 | +++++-- |
2 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/obj2vtk b/obj2vtk
@@ -20,23 +20,37 @@ set -e
die()
{
- rm -f "${tmp}" # cleanup temporary file
- exit "${1:-1}" # return status code (default is 1)
+ rm -f "${tmp}" # cleanup temporary file
+ exit "${1:-1}" # return status code (default is 1)
}
# Configure signal processing
trap 'die $?' EXIT
-# Temporary file
-tmp="$(mktemp "${TMPDIR:-/tmp}/obj2vtk_XXXXXX")"
+usage()
+{
+ >&2 printf 'usage: obj2vtk [file]\n'
+}
########################################################################
# Conversion script
########################################################################
-awk '$1 ~ "[fv]" {print $1, $2, $3, $4}' > "${tmp}"
+if [ "$#" -eq 0 ]; then # Read from stdin
+ tmp="$(mktemp "${TMPDIR:-/tmp}/obj2vtk_XXXXXX")"
+
+ awk '$1 ~ "[fv]" {print $1, $2, $3, $4}' > "${tmp}"
+ in="${tmp}"
+
+elif [ ! -f "$1" ]; then
+ usage
+ die 1
-nnodes="$(grep -ce '^v ' "${tmp}" || true)"
-ncells="$(grep -ce '^f ' "${tmp}" || true)"
+else
+ in="$1"
+fi
+
+nnodes="$(grep -cEe '^[ ]*v[ ]' "${in}" || true)"
+ncells="$(grep -cEe '^[ ]*f[ ]' "${in}" || true)"
[ "${ncells}" -eq 0 ] && die 0 # no triangle
@@ -46,20 +60,22 @@ printf 'ASCII\n'
printf 'DATASET POLYDATA\n'
printf 'POINTS %s double\n' "${nnodes}"
-grep -e '^v' "${tmp}" | cut -d' ' -f2-4
+
+# Add a "grep" directive to make the evaluation of the regular
+# expression and the stream treatment calculations concurrent, so that
+# they can be executed in parallel. This results in a slight improvement
+# in performance.
+grep -Ee '^[ ]*v[ ]' "${in}" | awk '{print $2, $3, $4}'
printf 'POLYGONS %s %s\n' "${ncells}" "$((ncells*4))"
-# Add a "grep" directive to make the evaluation of the regular
-# expression and the arithmetic calculations concurrent, so that they
-# can be executed in parallel. This results in a slight improvement in
-# performance.
+# See above to find out why "grep" is used in addition to "awk"
#
-# Note that the numeric conversion performed by awk(1) only takes the
-# first index of each vertex into account and ignores the others. See
-# strtod(3), which describes the conversion as it should be performed
-# by awk. Therefore, a vertex that has a texture and/or normal index
-# is still correctly handled without any additional processing.
-grep -e '^f' "${tmp}" | awk '{print 3, $2-1, $3-1, $4-1}'
+# The numeric conversion performed by awk(1) only takes the first index
+# of each vertex into account and ignores the others. See strtod(3),
+# which describes the conversion as it should be performed by awk.
+# Therefore, a vertex that has a texture and/or normal index is still
+# correctly handled without any additional processing.
+grep -Ee '^[ ]*f[ ]' "${in}" | awk '{print 3, $2-1, $3-1, $4-1}'
die 0
diff --git a/obj2vtk.1 b/obj2vtk.1
@@ -24,9 +24,12 @@
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh SYNOPSIS
.Nm
+.Op Ar file
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh DESCRIPTION
-Input data in Obj format is read from the standard input.
+If no input
+.Ar file
+is provided, the Obj data is read from the standard input.
The VTK mesh is written to the standard output.
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh EXIT
@@ -34,7 +37,7 @@ The VTK mesh is written to the standard output.
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh EXAMPLES
.Bd -literal
-obj2vtk < input.obj > output.vtk
+obj2vtk input.obj > output.vtk
.Ed
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh SEE ALSO