diff --git a/.gitignore b/.gitignore index b377e74..9823c9f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ *.la *.lo *.o +*~ diff --git a/INSTALL b/INSTALL index 2550dab..2099840 100644 --- a/INSTALL +++ b/INSTALL @@ -1,19 +1,25 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, +Inc. - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following + Briefly, the shell command `./configure && make && make install' +should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for -instructions specific to this package. +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -42,7 +48,7 @@ may remove or edit it. you want to change it or regenerate `configure' using a newer version of `autoconf'. -The simplest way to compile this package is: + The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. @@ -53,12 +59,22 @@ The simplest way to compile this package is: 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with - the package. + the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -67,8 +83,15 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. - 6. Often, you can also type `make uninstall' to remove the installed - files again. + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. Compilers and Options ===================== @@ -93,7 +116,8 @@ same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have @@ -120,7 +144,8 @@ Installation Names By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you @@ -131,15 +156,46 @@ Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -Optional Features -================= - Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE @@ -152,6 +208,13 @@ find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + Particular systems ================== @@ -163,6 +226,11 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended @@ -241,9 +309,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== @@ -288,7 +357,7 @@ operates. `configure' can determine that directory automatically. `--prefix=DIR' - Use DIR as the installation prefix. *Note Installation Names:: + Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. @@ -299,4 +368,3 @@ operates. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/Makefile.am b/Makefile.am index 3f084bf..1b02df8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = mash examples docs +SUBDIRS = mash docs ACLOCAL_AMFLAGS = -I m4 diff --git a/README b/README index 56e0031..8a7b2a5 100644 --- a/README +++ b/README @@ -1,3 +1,13 @@ +Note: During compiling, if you get the error +"libmash-0.2.la: file not recognized: File format not recognized" +search for --library in mash/Makefile and change it to +mash-0.2 + +To make a debian package: +dpkg-buildpackage -b -nc + +./configure --prefix=/usr --libdir=/usr/lib/arm-linux-gnueabihf + Mash - README =============================================================================== diff --git a/configure.ac b/configure.ac index 12ce0c3..c9e3b85 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl 1.0.0 release). The micro is odd numbered between releases. Only dnl on the commit that contains a release should it be an even number. m4_define([mash_major_version], [0]) -m4_define([mash_minor_version], [2]) +m4_define([mash_minor_version], [3]) m4_define([mash_micro_version], [1]) m4_define([mash_version], [mash_major_version.mash_minor_version.mash_micro_version]) @@ -35,7 +35,7 @@ AC_CONFIG_SRCDIR([mash/mash.h]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.9]) +AM_INIT_AUTOMAKE([1.14]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -105,6 +105,7 @@ AC_CONFIG_FILES([ Makefile mash/Makefile mash/rply/Makefile + mash/rstl/Makefile examples/Makefile docs/Makefile docs/reference/Makefile diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..149691e --- /dev/null +++ b/debian/changelog @@ -0,0 +1,12 @@ +mash (0.3.0-1) UNRELEASED; urgency=medium + + * Added shader with progress + + -- Elias Bakken Wed, 31 Aug 2016 14:19:39 +0000 + + +mash (0.2.0-1) UNRELEASED; urgency=medium + + * Initial release for Replicape + + -- Elias Bakken Mon, 13 Apr 2015 14:19:39 +0000 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..3fd22d3 --- /dev/null +++ b/debian/control @@ -0,0 +1,66 @@ +Source: mash +Section: libs +Priority: optional +Maintainer: Elias Bakken +Build-Depends: autoconf, + automake, + autotools-dev, + cdbs (>= 0.4.93~), + debhelper (>= 9), + dh-autoreconf, + gir1.2-clutter-1.0, + gir1.2-json-1.0, + gobject-introspection (>= 0.10.0), + libclutter-1.0-dev, + libdbus-glib-1-dev, + libgirepository1.0-dev (>= 0.10.0), + libtool, +Standards-Version: 3.9.5 +Homepage: http://www.clutter-project.org/ + +Package: libmash-0.3-0 +Section: libs +Architecture: any +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends} +Multi-Arch: same +Description: Mash is a small library for using real 3D models within a Clutter + scene. Models can be exported from Blender or other 3D modelling + software as PLY files and then used as actors. It also supports a + lighting model with animatable lights. + +Package: libmash-dev +Section: libdevel +Architecture: any +Depends: autotools-dev, + gir1.2-mash-0.3-0 (= ${binary:Version}), + libclutter-1.0-dev, + libmash-0.3-0 (= ${binary:Version}), + ${misc:Depends} +Description: Mash is a small library for using real 3D models within a Clutter + scene. Models can be exported from Blender or other 3D modelling + software as PLY files and then used as actors. It also supports a + lighting model with animatable lights. + . + This package contains the development files. + +Package: libmash-0.3-0-dbg +Architecture: any +Section: debug +Priority: extra +Depends: libmash-0.3-0 (=${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: Mash is a small library for using real 3D models within a Clutter + scene. Models can be exported from Blender or other 3D modelling + software as PLY files and then used as actors. It also supports a + lighting model with animatable lights. + . + This package contains the debug symbols + +Package: gir1.2-mash-0.3-0 +Architecture: any +Section: introspection +Depends: ${gir:Depends}, ${misc:Depends}, ${shlibs:Depends} +Description: GObject introspection data for the libmash library + This package can be used by other packages using the GIRepository format + to generate dynamic bindings for libmash. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8f3d112 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,5 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: mash +Upstream-Contact: Emmanuele Bassi + Thomas Wood +Source: http://source.clutter-project.org/sources/mash diff --git a/debian/gir1.2-mash-0.2-0.install b/debian/gir1.2-mash-0.2-0.install new file mode 100644 index 0000000..03255f6 --- /dev/null +++ b/debian/gir1.2-mash-0.2-0.install @@ -0,0 +1 @@ +usr/lib/*/girepository-1.0/ usr/lib/ diff --git a/debian/gir1.2-mash-0.3-0.install b/debian/gir1.2-mash-0.3-0.install new file mode 100644 index 0000000..03255f6 --- /dev/null +++ b/debian/gir1.2-mash-0.3-0.install @@ -0,0 +1 @@ +usr/lib/*/girepository-1.0/ usr/lib/ diff --git a/debian/libmash-0.2-0.install b/debian/libmash-0.2-0.install new file mode 100644 index 0000000..0575530 --- /dev/null +++ b/debian/libmash-0.2-0.install @@ -0,0 +1 @@ +usr/lib/arm-linux-gnueabihf/*.so.* diff --git a/debian/libmash-0.3-0.install b/debian/libmash-0.3-0.install new file mode 100644 index 0000000..0575530 --- /dev/null +++ b/debian/libmash-0.3-0.install @@ -0,0 +1 @@ +usr/lib/arm-linux-gnueabihf/*.so.* diff --git a/debian/libmash-dev.install b/debian/libmash-dev.install new file mode 100644 index 0000000..ab856aa --- /dev/null +++ b/debian/libmash-dev.install @@ -0,0 +1,4 @@ +usr/include/ +usr/lib/arm-linux-gnueabihf/*.so +usr/lib/arm-linux-gnueabihf/pkgconfig/*.pc +usr/share/gir-1.0/ diff --git a/debian/mash-create-image-cache.sgml b/debian/mash-create-image-cache.sgml new file mode 100644 index 0000000..3581895 --- /dev/null +++ b/debian/mash-create-image-cache.sgml @@ -0,0 +1,118 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + Ying-Chun"> + Liu"> + + September 5, 2009"> + + 1"> + paulliu@debian.org"> + + mx"> + + + Debian"> + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2009 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + program to make a cache of a directory + + + + + &dhpackage; + + + + + DESCRIPTION + + This manual page documents briefly the + &dhpackage; command. + + This manual page was written for the &debian; distribution + because the original program does not have a manual page. + + &dhpackage; is a prgram to make a cache for + a directory which contains images. It will create a cached image inside + /var/cache/mx for all the images inside that directory and + its sub-directories. + + + + + AUTHOR + + This manual page was written by &dhusername; &dhemail; for + the &debian; system (and may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the &gnu; Lesser General Public License, + version 2.1 or any + later version published by the Free Software Foundation. + + + On Debian systems, the complete text of the GNU Lesser General Public + License can be found in /usr/share/common-licenses/LGPL-2.1. + + + +
+ + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..a992415 --- /dev/null +++ b/debian/rules @@ -0,0 +1,19 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/autoreconf.mk +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/autotools.mk +include /usr/share/cdbs/1/rules/utils.mk + +DEB_DH_AUTORECONF_ARGS := $(CURDIR)/autogen.sh +DEB_CONFIGURE_EXTRA_FLAGS :=--enable-introspection --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) + +clean:: + find . -type f -name ".gitignore" -exec rm -f {} \; + +reconf: + intltoolize --force --copy --automake + gtkdocize + autoreconf -f -i -v + +common-binary-predeb-arch:: list-missing diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..c23f23d --- /dev/null +++ b/debian/watch @@ -0,0 +1,4 @@ +version=3 +http://source.clutter-project.org/sources/mx/([\d]+[\d\.]*)/mx-([\d\.]*)\.tar\.bz2 +opts=uversionmangle=s/_/./g;s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)[\-\.]?\d*)$/$1~$2/ \ +https://github.com/clutter-project/mx/tags .*[^n]/(?:v||release-|mx[_\-])(\d.*)\.(?:tgz|tbz2|txz|tar\.(?:gz|bz2|xz)) diff --git a/examples/Makefile.am b/examples/Makefile.am index 64d6dd6..0d11c1c 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,11 +1,9 @@ noinst_PROGRAMS = viewer -INCLUDES = \ - -I $(top_srcdir) \ - -I $(top_builddir) \ - -I $(top_builddir)/mash - AM_CPPFLAGS = \ + -I $(top_srcdir) \ + -I $(top_builddir) \ + -I $(top_builddir)/mash @CLUTTER_CFLAGS@ viewer_SOURCES = \ diff --git a/examples/lights.c b/examples/lights.c index 4cfac6e..e52bd1f 100644 --- a/examples/lights.c +++ b/examples/lights.c @@ -554,7 +554,7 @@ main (int argc, char **argv) CoglHandle material; float maximum_shininess; - material = mash_model_get_material (MASH_MODEL (data.model)); + material = mash_model_get_pipeline (MASH_MODEL (data.model)); /* Before version 1.3.10 on the 1.3 branch and 1.2.14 on the 1.2 branch Cogl would remap the shininess property to the range diff --git a/examples/viewer.c b/examples/viewer.c index 0247d60..05ee4f1 100644 --- a/examples/viewer.c +++ b/examples/viewer.c @@ -69,7 +69,7 @@ main (int argc, char **argv) cogl_material_set_layer (material, 0, texture); cogl_handle_unref (texture); - mash_model_set_material (MASH_MODEL (model), + mash_model_set_pipeline (MASH_MODEL (model), material); cogl_handle_unref (material); diff --git a/mash/Makefile.am b/mash/Makefile.am index 25fde1f..a418ad2 100644 --- a/mash/Makefile.am +++ b/mash/Makefile.am @@ -1,11 +1,10 @@ -SUBDIRS = rply +#AUTOMAKE_OPTIONS = subdir-objects +SUBDIRS = rply rstl lib_LTLIBRARIES = libmash-@MASH_API_VERSION@.la -INCLUDES = \ - -I$(top_srcdir) - AM_CPPFLAGS = \ + -I$(top_srcdir) \ -DMASH_COMPILATION=1 \ @CLUTTER_CFLAGS@ @@ -15,7 +14,8 @@ enum_h = \ private_h = \ $(srcdir)/mash-data-loaders.h \ $(srcdir)/mash-data-loader.h \ - $(srcdir)/mash-ply-loader.h + $(srcdir)/mash-ply-loader.h \ + $(srcdir)/mash-stl-loader.h public_h = \ $(enum_h) \ @@ -38,7 +38,8 @@ built_source_c = \ $(builddir)/mash-enum-types.c loaders_c = \ - $(srcdir)/mash-ply-loader.c + $(srcdir)/mash-ply-loader.c \ + $(srcdir)/mash-stl-loader.c libmash_@MASH_API_VERSION@_la_SOURCES = \ $(source_h) \ @@ -69,7 +70,8 @@ libmash_@MASH_API_VERSION@_la_LDFLAGS = \ libmash_@MASH_API_VERSION@_la_LIBADD = \ @CLUTTER_LIBS@ \ - rply/librply.la + rply/librply.la \ + rstl/librstl.la CLEANFILES = @@ -87,7 +89,7 @@ Mash-@MASH_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libmash-@MASH_API_VERSION@ --c-include='mash/mash.h' \ --include=Clutter-1.0 \ --output $@ \ - --library=libmash-@MASH_API_VERSION@.la \ + --library=mash-@MASH_API_VERSION@ --library-path=$(realpath $(top_srcdir))/mash/.libs/\ $(libmash_@MASH_API_VERSION@_la_SOURCES) BUILT_GIRSOURCES += Mash-@MASH_API_VERSION@.gir diff --git a/mash/mash-data-loader.h b/mash/mash-data-loader.h index fe88344..799248e 100644 --- a/mash/mash-data-loader.h +++ b/mash/mash-data-loader.h @@ -102,6 +102,8 @@ struct _MashDataLoaderData /* Bounding cuboid of the data */ ClutterVertex min_vertex, max_vertex; + + CoglPrimitive *prim; }; GType mash_data_loader_get_type (void) G_GNUC_CONST; diff --git a/mash/mash-data-loaders.h b/mash/mash-data-loaders.h index 24567bb..075a8e3 100644 --- a/mash/mash-data-loaders.h +++ b/mash/mash-data-loaders.h @@ -25,5 +25,6 @@ #define __MASH_DATA_LOADERS_H__ #include "mash-ply-loader.h" +#include "mash-stl-loader.h" #endif /* __MASH_DATA_LOADERS_H__ */ diff --git a/mash/mash-data.c b/mash/mash-data.c index ffd243d..5c841bd 100644 --- a/mash/mash-data.c +++ b/mash/mash-data.c @@ -41,6 +41,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include "mash-data.h" #include "mash-data-loader.h" #include "mash-data-loaders.h" @@ -53,14 +60,12 @@ G_DEFINE_TYPE (MashData, mash_data, G_TYPE_OBJECT); (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MASH_TYPE_DATA, \ MashDataPrivate)) -struct _MashDataPrivate -{ +struct _MashDataPrivate{ MashDataLoaderData loaded_data; }; static void -mash_data_class_init (MashDataClass *klass) -{ +mash_data_class_init (MashDataClass *klass){ GObjectClass *gobject_class = (GObjectClass *) klass; gobject_class->finalize = mash_data_finalize; @@ -69,18 +74,15 @@ mash_data_class_init (MashDataClass *klass) } static void -mash_data_init (MashData *self) -{ +mash_data_init (MashData *self){ self->priv = MASH_DATA_GET_PRIVATE (self); } static void -mash_data_free_vbos (MashData *self) -{ +mash_data_free_vbos (MashData *self){ MashDataPrivate *priv = self->priv; - if (priv->loaded_data.vertices_vbo) - { + if (priv->loaded_data.vertices_vbo){ cogl_handle_unref (priv->loaded_data.vertices_vbo); priv->loaded_data.vertices_vbo = NULL; } @@ -93,8 +95,7 @@ mash_data_free_vbos (MashData *self) } static void -mash_data_finalize (GObject *object) -{ +mash_data_finalize (GObject *object){ MashData *self = (MashData *) object; mash_data_free_vbos (self); @@ -112,8 +113,7 @@ mash_data_finalize (GObject *object) * Return value: a new #MashData. */ MashData * -mash_data_new (void) -{ +mash_data_new (void){ MashData *self = g_object_new (MASH_TYPE_DATA, NULL); return self; @@ -137,8 +137,7 @@ gboolean mash_data_load (MashData *self, MashDataFlags flags, const gchar *filename, - GError **error) -{ + GError **error){ MashDataPrivate *priv; MashDataLoader *loader; gchar *display_name; @@ -153,13 +152,13 @@ mash_data_load (MashData *self, if (g_str_has_suffix (filename, ".ply")) loader = g_object_new (MASH_TYPE_PLY_LOADER, NULL); + else if (g_str_has_suffix (g_ascii_strdown(filename, -1), ".stl")) + loader = g_object_new (MASH_TYPE_STL_LOADER, NULL); - if (loader != NULL) - { + if (loader != NULL){ if (!mash_data_loader_load (loader, flags, filename, error)) ret = FALSE; - else - { + else{ /* Get rid of the old VBOs (if any) */ mash_data_free_vbos (self); @@ -167,10 +166,8 @@ mash_data_load (MashData *self, ret = TRUE; } } - else - { + else{ /* Unknown file format */ - g_set_error (error, MASH_DATA_ERROR, MASH_DATA_ERROR_UNKNOWN_FORMAT, "Unknown format for file %s", @@ -197,24 +194,23 @@ mash_data_load (MashData *self, * the paint method of the model. */ void -mash_data_render (MashData *self) -{ - MashDataPrivate *priv; - - g_return_if_fail (MASH_IS_DATA (self)); - - priv = self->priv; - - /* Silently fail if we didn't load any data */ - if (priv->loaded_data.vertices_vbo == NULL || priv->loaded_data.indices == NULL) - return; - - cogl_vertex_buffer_draw_elements (priv->loaded_data.vertices_vbo, +mash_data_render (MashData *self, CoglPipeline* pl){ + MashDataPrivate *priv; + g_return_if_fail (MASH_IS_DATA (self)); + priv = self->priv; + + if (priv->loaded_data.prim != NULL){ + CoglFramebuffer *fb = /*(CoglFramebuffer*)*/ cogl_get_draw_framebuffer(); + cogl_primitive_draw(priv->loaded_data.prim, fb, pl); + } + else if(priv->loaded_data.vertices_vbo != NULL && priv->loaded_data.indices != NULL){ + cogl_vertex_buffer_draw_elements (priv->loaded_data.vertices_vbo, COGL_VERTICES_MODE_TRIANGLES, priv->loaded_data.indices, priv->loaded_data.min_index, priv->loaded_data.max_index, 0, priv->loaded_data.n_triangles * 3); + } } /** diff --git a/mash/mash-data.h b/mash/mash-data.h index eee1234..a82e267 100644 --- a/mash/mash-data.h +++ b/mash/mash-data.h @@ -151,7 +151,7 @@ gboolean mash_data_load (MashData *self, const gchar *filename, GError **error); -void mash_data_render (MashData *self); +void mash_data_render (MashData *self, CoglPipeline *pl); GQuark mash_data_error_quark (void); diff --git a/mash/mash-directional-light.c b/mash/mash-directional-light.c index 32b4d7f..55d7349 100644 --- a/mash/mash-directional-light.c +++ b/mash/mash-directional-light.c @@ -49,7 +49,7 @@ static void mash_directional_light_generate_shader (MashLight *light, GString *uniform_source, GString *main_source); static void mash_directional_light_update_uniforms (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); G_DEFINE_TYPE (MashDirectionalLight, mash_directional_light, MASH_TYPE_LIGHT); @@ -154,7 +154,7 @@ mash_directional_light_generate_shader (MashLight *light, static void mash_directional_light_update_uniforms (MashLight *light, - CoglHandle program) + CoglPipeline *pipeline) { MashDirectionalLight *dlight = MASH_DIRECTIONAL_LIGHT (light); MashDirectionalLightPrivate *priv = dlight->priv; @@ -163,12 +163,12 @@ mash_directional_light_update_uniforms (MashLight *light, static const float light_direction[4] = { 0.0f, -1.0f, 0.0f, 0.0f }; MASH_LIGHT_CLASS (mash_directional_light_parent_class) - ->update_uniforms (light, program); + ->update_uniforms (light, pipeline); if (priv->uniform_locations_dirty) { priv->light_direction_uniform_location - = mash_light_get_uniform_location (light, program, "light_direction"); + = mash_light_get_uniform_location (light, pipeline, "light_direction"); priv->uniform_locations_dirty = FALSE; } @@ -179,7 +179,7 @@ mash_directional_light_update_uniforms (MashLight *light, allocation */ mash_light_set_direction_uniform (light, - program, + pipeline, priv->light_direction_uniform_location, light_direction); } diff --git a/mash/mash-light-set.c b/mash/mash-light-set.c index 15d5bd3..bd2ba66 100644 --- a/mash/mash-light-set.c +++ b/mash/mash-light-set.c @@ -72,7 +72,7 @@ static void mash_light_set_finalize (GObject *object); static gboolean mash_light_set_repaint_func (gpointer data); -static float mash_light_set_get_shininess_wrapper (CoglMaterial *material); +static float mash_light_set_get_shininess_wrapper (CoglPipeline *pipeline); G_DEFINE_TYPE (MashLightSet, mash_light_set, G_TYPE_OBJECT); @@ -80,10 +80,10 @@ G_DEFINE_TYPE (MashLightSet, mash_light_set, G_TYPE_OBJECT); (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MASH_TYPE_LIGHT_SET, \ MashLightSetPrivate)) -typedef void (* MaterialColorGetFunc) (CoglMaterial *material, +typedef void (* MaterialColorGetFunc) (CoglPipeline *pipeline, CoglColor *color); -typedef float (* MaterialFloatGetFunc) (CoglMaterial *material); +typedef float (* MaterialFloatGetFunc) (CoglPipeline *pipeline); typedef enum { @@ -102,22 +102,22 @@ mash_light_set_material_properties[] = { MATERIAL_PROP_TYPE_COLOR, "mash_material.emission", - cogl_material_get_emission + cogl_pipeline_get_emission }, { MATERIAL_PROP_TYPE_COLOR, "mash_material.ambient", - cogl_material_get_ambient + cogl_pipeline_get_ambient }, { MATERIAL_PROP_TYPE_COLOR, "mash_material.diffuse", - cogl_material_get_diffuse + cogl_pipeline_get_diffuse }, { MATERIAL_PROP_TYPE_COLOR, "mash_material.specular", - cogl_material_get_specular + cogl_pipeline_get_specular }, { MATERIAL_PROP_TYPE_FLOAT, @@ -128,7 +128,7 @@ mash_light_set_material_properties[] = struct _MashLightSetPrivate { - CoglHandle program; + CoglPipeline *pipeline; /* This is the layer indices that the pipeline contained the last * time the program was generated. If these change then we need to @@ -147,6 +147,8 @@ struct _MashLightSetPrivate need to update the uniforms on the program before painting any actor */ gboolean uniforms_dirty; + + gboolean pipeline_created; }; static void @@ -171,6 +173,7 @@ mash_light_set_init (MashLightSet *self) clutter_threads_add_repaint_func (mash_light_set_repaint_func, self, NULL); priv->layer_indices = g_array_new (FALSE, FALSE, sizeof (int)); + priv->pipeline_created = FALSE; } static void @@ -198,8 +201,8 @@ mash_light_set_finalize (GObject *object) MashLightSet *self = (MashLightSet *) object; MashLightSetPrivate *priv = self->priv; - if (priv->program) - cogl_handle_unref (priv->program); + if (priv->pipeline) + cogl_handle_unref (priv->pipeline); g_array_free (priv->layer_indices, TRUE); @@ -236,122 +239,113 @@ add_layer_indices (MashLightSet *light_set, } } -static CoglHandle -mash_light_set_get_program (MashLightSet *light_set) -{ +void +mash_light_set_get_pipeline (MashLightSet *light_set, CoglPipeline* pipeline){ + MashLightSetPrivate *priv = light_set->priv; + GString *uniform_source, *main_source; + char *uniform_char, *main_char; + CoglHandle shader; + char *info_log; + GSList *l; + int i; - if (priv->program == COGL_INVALID_HANDLE) - { - GString *uniform_source, *main_source; - char *full_source; - CoglHandle shader; - char *info_log; - GSList *l; - int i; + uniform_source = g_string_new (NULL); + main_source = g_string_new (NULL); + + /* Append the shader boiler plate */ + g_string_append (uniform_source, + "\n" + "uniform mat3 mash_normal_matrix;\n" + "\n" + "struct MashMaterialParameters {\n" + " vec4 emission;\n" + " vec4 ambient;\n" + " vec4 diffuse;\n" + " vec4 specular;\n" + " float shininess;\n" + "};\n" + "\n" + "uniform MashMaterialParameters mash_material;\n"); + g_string_append (main_source, + /* Start with just the light emitted by the + object itself. The lights should add to this + color */ + " cogl_color_out = mash_material.emission;\n" + /* Calculate a transformed and normalized vertex normal */ + " vec3 normal = normalize (mash_normal_matrix * cogl_normal_in);\n" + /* Calculate the vertex position in eye coordinates */ + " vec4 homogenous_eye_coord = cogl_modelview_matrix * cogl_position_in;\n" + " vec3 eye_coord = homogenous_eye_coord.xyz / homogenous_eye_coord.w;\n"); + + + /* Give all of the lights in the scene a chance to modify the + shader source */ + for (l = priv->lights; l; l = l->next) + mash_light_generate_shader (l->data, + uniform_source, + main_source); - uniform_source = g_string_new (NULL); - main_source = g_string_new (NULL); - /* Give all of the lights in the scene a chance to modify the - shader source */ - for (l = priv->lights; l; l = l->next) - mash_light_generate_shader (l->data, - uniform_source, - main_source); - - /* Append the shader boiler plate */ - g_string_append (uniform_source, - "\n" - "uniform mat3 mash_normal_matrix;\n" - "\n" - "struct MashMaterialParameters {\n" - " vec4 emission;\n" - " vec4 ambient;\n" - " vec4 diffuse;\n" - " vec4 specular;\n" - " float shininess;\n" - "};\n" - "\n" - "uniform MashMaterialParameters mash_material;\n" - "\n" - "void\n" - "main ()\n" - "{\n" - /* Start with just the light emitted by the - object itself. The lights should add to this - color */ - " cogl_color_out = mash_material.emission;\n" - /* Calculate a transformed and normalized - vertex normal */ - " vec3 normal = normalize (mash_normal_matrix\n" - " * cogl_normal_in);\n" - /* Calculate the vertex position in eye coordinates */ - " vec4 homogenous_eye_coord\n" - " = cogl_modelview_matrix * cogl_position_in;\n" - " vec3 eye_coord = homogenous_eye_coord.xyz\n" - " / homogenous_eye_coord.w;\n"); - /* Append the main source to the uniform source to get the full - source for the shader */ - g_string_append_len (uniform_source, - main_source->str, - main_source->len); - /* Perform the standard vertex transformation and copy the - texture coordinates. FIXME: Ideally this could should be - updated to use CoglSnippets so that it doesn't have to do - this. */ - g_string_append (uniform_source, - " cogl_position_out =\n" - " cogl_modelview_projection_matrix *\n" - " cogl_position_in;\n"); - - add_layer_indices (light_set, uniform_source); - - g_string_append (uniform_source, - "}\n"); - - full_source = g_string_free (uniform_source, FALSE); - g_string_free (main_source, TRUE); - - priv->program = cogl_create_program (); - - shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX); - cogl_shader_source (shader, full_source); - g_free (full_source); - cogl_shader_compile (shader); - - if (!cogl_shader_is_compiled (shader)) - g_warning ("Error compiling light box shader"); - - info_log = cogl_shader_get_info_log (shader); - - if (info_log) - { - if (*info_log) - g_warning ("The light box shader has an info log:\n%s", info_log); + /* Perform the standard vertex transformation and copy the + texture coordinates. */ + g_string_append (main_source, + " cogl_position_out = cogl_modelview_projection_matrix * cogl_position_in;\n"); + + add_layer_indices (light_set, main_source); - g_free (info_log); - } + uniform_char = g_string_free (uniform_source, FALSE); + main_char = g_string_free (main_source, FALSE); - cogl_program_attach_shader (priv->program, shader); - cogl_program_link (priv->program); + CoglSnippet *snippet_vertex; + snippet_vertex = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, + uniform_char, main_char); - priv->normal_matrix_uniform = - cogl_program_get_uniform_location (priv->program, "mash_normal_matrix"); - for (i = 0; i < G_N_ELEMENTS (mash_light_set_material_properties); i++) - { - const char *uniform_name = - mash_light_set_material_properties[i].uniform_name; + /* Add it to the pipeline */ + cogl_pipeline_add_snippet (pipeline, snippet_vertex); + /* The pipeline keeps a reference to the snippet + so we don't need to */ + cogl_object_unref (snippet_vertex); - priv->material_uniforms[i] = - cogl_program_get_uniform_location (priv->program, uniform_name); - } - } + priv->normal_matrix_uniform = cogl_pipeline_get_uniform_location (pipeline, "mash_normal_matrix"); - return priv->program; + for (i = 0; i < G_N_ELEMENTS (mash_light_set_material_properties); i++){ + const char *uniform_name = mash_light_set_material_properties[i].uniform_name; + priv->material_uniforms[i] = cogl_pipeline_get_uniform_location (pipeline, uniform_name); + } } +void +mash_light_set_get_snippets (MashLightSet *light_set){ + + MashLightSetPrivate *priv = light_set->priv; + GString *uniform_source, *main_source; + char *uniform_char, *main_char; + CoglHandle shader; + char *info_log; + GSList *l; + int i; + + // TODO: Let each light generate it's own snippet. + + CoglSnippet *main = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS, NULL, NULL); + + cogl_snippet_set_declarations(main, + "uniform mat3 mash_normal_matrix;\n" + "\n" + "struct MashMaterialParameters {\n" + " vec4 emission;\n" + " vec4 ambient;\n" + " vec4 diffuse;\n" + " vec4 specular;\n" + " float shininess;\n" + "};\n" + "\n" + "uniform MashMaterialParameters mash_material;\n"); +} + + static void mash_light_set_dirty_program (MashLightSet *light_set) { @@ -359,11 +353,10 @@ mash_light_set_dirty_program (MashLightSet *light_set) /* If we've added or removed a light then we need to regenerate the shader */ - if (priv->program != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->program); - priv->program = COGL_INVALID_HANDLE; - } + priv->pipeline_created = FALSE; + // TODO: Keep a list of pipelines, so each can be recreated. + // Right now, pipelines can not be set to NULL, since they + // already have color and possibly a fragment shader. } typedef struct @@ -377,13 +370,11 @@ typedef struct static CoglBool update_layer_indices_cb (CoglPipeline *pipeline, int layer_index, - void *user_data) -{ + void *user_data){ UpdateLayerIndicesData *data = user_data; MashLightSetPrivate *priv = data->light_set->priv; - if (data->is_matching) - { + if (data->is_matching){ if (data->index_num >= priv->layer_indices->len || g_array_index (priv->layer_indices, int, @@ -396,28 +387,25 @@ update_layer_indices_cb (CoglPipeline *pipeline, if (!data->is_matching) g_array_append_val (priv->layer_indices, layer_index); - data->index_num++; - return TRUE; } -static void -update_layer_indices (MashLightSet *light_set, - CoglHandle material) +gboolean +mash_light_set_update_layer_indices (MashLightSet *light_set, + CoglPipeline *pipeline) { MashLightSetPrivate *priv = light_set->priv; UpdateLayerIndicesData data; data.light_set = light_set; - data.pipeline = COGL_PIPELINE (material); + data.pipeline = pipeline; data.is_matching = TRUE; data.index_num = 0; cogl_pipeline_foreach_layer (data.pipeline, update_layer_indices_cb, &data); - /* If the layer indices have changed then we need to regenerate the * program */ if (!data.is_matching || @@ -425,7 +413,10 @@ update_layer_indices (MashLightSet *light_set, { g_array_set_size (priv->layer_indices, data.index_num); mash_light_set_dirty_program (light_set); + + return TRUE; } + return FALSE; } /** @@ -452,33 +443,31 @@ update_layer_indices (MashLightSet *light_set, * * Since: 0.2 */ -CoglHandle +void mash_light_set_begin_paint (MashLightSet *light_set, - CoglHandle material) -{ + CoglPipeline *pipeline){ MashLightSetPrivate *priv = light_set->priv; - CoglHandle program; int i; - update_layer_indices (light_set, material); + priv->pipeline = pipeline; - program = mash_light_set_get_program (light_set); + if(!cogl_is_pipeline(pipeline)) + return; - if (priv->uniforms_dirty) - { - GSList *l; + //mash_light_set_update_layer_indices (light_set, pipeline); + if (priv->uniforms_dirty){ + GSList *l; /* Give all of the lights a chance to update the uniforms before we paint the first actor using the light set */ for (l = priv->lights; l; l = l->next) - mash_light_update_uniforms (l->data, program); + mash_light_update_uniforms (l->data, pipeline); - priv->uniforms_dirty = FALSE; + //priv->uniforms_dirty = FALSE; } /* Calculate the normal matrix from the modelview matrix */ - if (priv->normal_matrix_uniform != -1) - { + if (priv->normal_matrix_uniform != -1){ CoglMatrix modelview_matrix; CoglMatrix inverse_matrix; float transpose_matrix[3 * 3]; @@ -500,7 +489,7 @@ mash_light_set_begin_paint (MashLightSet *light_set, transpose_matrix[7] = inverse_matrix.zy; transpose_matrix[8] = inverse_matrix.zz; - cogl_program_set_uniform_matrix (program, + cogl_pipeline_set_uniform_matrix (pipeline, priv->normal_matrix_uniform, 3, /* dimensions */ 1, /* count */ @@ -519,14 +508,14 @@ mash_light_set_begin_paint (MashLightSet *light_set, mash_light_set_material_properties[i].get_func; float vec[4]; - get_func (material, &color); + get_func (pipeline, &color); vec[0] = cogl_color_get_red_float (&color); vec[1] = cogl_color_get_green_float (&color); vec[2] = cogl_color_get_blue_float (&color); vec[3] = cogl_color_get_alpha_float (&color); - cogl_program_set_uniform_float (program, + cogl_pipeline_set_uniform_float (pipeline, priv->material_uniforms[i], 4, /* n_components */ 1, /* count */ @@ -540,16 +529,14 @@ mash_light_set_begin_paint (MashLightSet *light_set, mash_light_set_material_properties[i].get_func; float value; - value = get_func (material); + value = get_func (pipeline); - cogl_program_set_uniform_1f (program, + cogl_pipeline_set_uniform_1f (pipeline, priv->material_uniforms[i], value); } break; } - - return program; } static gboolean @@ -631,7 +618,7 @@ mash_light_set_remove_light (MashLightSet *light_set, } static float -mash_light_set_get_shininess_wrapper (CoglMaterial *material) +mash_light_set_get_shininess_wrapper (CoglPipeline *pipeline) { float shininess; @@ -646,7 +633,7 @@ mash_light_set_get_shininess_wrapper (CoglMaterial *material) CoglMaterial is 0 so it's quite likely that an application would hit this if they are trying not to use specular lighting */ - shininess = cogl_material_get_shininess (material); + shininess = cogl_pipeline_get_shininess (pipeline); return MAX (0.0001, shininess); } diff --git a/mash/mash-light-set.h b/mash/mash-light-set.h index 20c21d3..3f1588e 100644 --- a/mash/mash-light-set.h +++ b/mash/mash-light-set.h @@ -87,8 +87,14 @@ void mash_light_set_add_light (MashLightSet *light_set, void mash_light_set_remove_light (MashLightSet *light_set, MashLight *light); -CoglHandle mash_light_set_begin_paint (MashLightSet *light_set, - CoglHandle material); +void mash_light_set_begin_paint (MashLightSet *light_set, + CoglPipeline *pipeline); + + +gboolean mash_light_set_update_layer_indices (MashLightSet *light_set, + CoglPipeline *pipeline); + +void mash_light_set_get_pipeline (MashLightSet *light_set, CoglPipeline* pipeline); G_END_DECLS diff --git a/mash/mash-light.c b/mash/mash-light.c index 592de87..8b3eb8a 100644 --- a/mash/mash-light.c +++ b/mash/mash-light.c @@ -44,6 +44,9 @@ #include #endif +#define CLUTTER_ENABLE_EXPERIMENTAL_API +#define COGL_ENABLE_EXPERIMENTAL_API + #include #include #include @@ -64,7 +67,7 @@ static void mash_light_real_generate_shader (MashLight *light, GString *uniform_source, GString *main_source); static void mash_light_real_update_uniforms (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); /* Length in characters not including any terminating NULL of the unique string that we append to uniform symbols */ @@ -189,7 +192,7 @@ mash_light_init (MashLight *self) unique to this */ gid = clutter_actor_get_gid (CLUTTER_ACTOR (self)); g_snprintf (priv->unique_str, MASH_LIGHT_UNIQUE_SYMBOL_SIZE + 1, - "g%08" G_GUINT32_FORMAT, gid); + "g%08" G_GUINT32_FORMAT, self); for (i = 0; i < MASH_LIGHT_COLOR_COUNT; i++) priv->light_colors[i] = mash_light_default_color; @@ -496,7 +499,7 @@ mash_light_generate_shader (MashLight *light, /** * mash_light_update_uniforms: * @light: The #MashLight that needs updating - * @program: A #CoglProgram containing the uniforms + * @program: A #CoglPipeline containing the uniforms * * This function is used by #MashLightSet to implement the lights. It * should not need to be called by an application directly. @@ -518,11 +521,13 @@ mash_light_generate_shader (MashLight *light, * in mash_light_append_shader(). */ void -mash_light_update_uniforms (MashLight *light, CoglHandle program) +mash_light_update_uniforms (MashLight *light, CoglPipeline *pipeline) { g_return_if_fail (MASH_IS_LIGHT (light)); - MASH_LIGHT_GET_CLASS (light)->update_uniforms (light, program); + //fprintf(stderr, "mash_light_update_uniforms\n"); + + MASH_LIGHT_GET_CLASS (light)->update_uniforms (light, pipeline); } /** @@ -595,7 +600,7 @@ mash_light_append_shader (MashLight *light, */ int mash_light_get_uniform_location (MashLight *light, - CoglHandle program, + CoglPipeline *pipeline, const char *uniform_name) { MashLightPrivate *priv; @@ -609,7 +614,7 @@ mash_light_get_uniform_location (MashLight *light, /* Append this light's unique identifier to the uniform name */ unique_name = g_strconcat (uniform_name, priv->unique_str, NULL); - location = cogl_program_get_uniform_location (program, unique_name); + location = cogl_pipeline_get_uniform_location (pipeline, unique_name); g_free (unique_name); @@ -702,7 +707,7 @@ mash_light_get_modelview_matrix (MashLight *light, */ void mash_light_set_direction_uniform (MashLight *light, - CoglHandle program, + CoglPipeline *pipeline, int uniform_location, const float *direction_in) { @@ -734,7 +739,7 @@ mash_light_set_direction_uniform (MashLight *light, light_direction[1] /= magnitude; light_direction[2] /= magnitude; - cogl_program_set_uniform_float (program, + cogl_pipeline_set_uniform_float (pipeline, uniform_location, 3, 1, light_direction); @@ -762,7 +767,7 @@ mash_light_real_generate_shader (MashLight *light, static void mash_light_real_update_uniforms (MashLight *light, - CoglHandle program) + CoglPipeline *pipeline) { MashLightPrivate *priv = light->priv; int i; @@ -777,7 +782,7 @@ mash_light_real_update_uniforms (MashLight *light, { for (i = 0; i < MASH_LIGHT_COLOR_COUNT; i++) priv->uniform_locations[i] - = mash_light_get_uniform_location (light, program, + = mash_light_get_uniform_location (light, pipeline, mash_light_color_names[i]); priv->uniform_locations_dirty = FALSE; @@ -793,7 +798,7 @@ mash_light_real_update_uniforms (MashLight *light, vec[1] = color->green / 255.0f; vec[2] = color->blue / 255.0f; - cogl_program_set_uniform_float (program, + cogl_pipeline_set_uniform_float (pipeline, priv->uniform_locations[i], 3, 1, vec); } diff --git a/mash/mash-light.h b/mash/mash-light.h index ef16104..2f1098c 100644 --- a/mash/mash-light.h +++ b/mash/mash-light.h @@ -67,7 +67,7 @@ struct _MashLightClass GString *uniform_source, GString *main_source); void (* update_uniforms) (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); }; /** @@ -98,10 +98,10 @@ void mash_light_generate_shader (MashLight *light, GString *uniform_source, GString *main_source); void mash_light_update_uniforms (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); int mash_light_get_uniform_location (MashLight *light, - CoglHandle program, + CoglPipeline *pipeline, const char *uniform_name); void mash_light_append_shader (MashLight *light, @@ -112,7 +112,7 @@ void mash_light_get_modelview_matrix (MashLight *light, CoglMatrix *matrix); void mash_light_set_direction_uniform (MashLight *light, - CoglHandle program, + CoglPipeline *pipeline, int uniform_location, const float *direction_in); diff --git a/mash/mash-model.c b/mash/mash-model.c index 77c424b..75e99c7 100644 --- a/mash/mash-model.c +++ b/mash/mash-model.c @@ -40,28 +40,28 @@ * existing actor then call mash_model_set_data() with the * return value on a new actor. * - * The model can be rendered with any Cogl material. By default the - * model will use a solid white material. The material color is - * blended with the model's vertex colors so the white material will + * The model can be rendered with any Cogl pipeline. By default the + * model will use a solid white pipeline. The pipeline color is + * blended with the model's vertex colors so the white pipeline will * cause the vertex colors to be used directly. #MashData is * able to load texture coordinates from the PLY file so it is * possible to render a textured model by setting a texture layer on - * the material, like so: + * the pipeline, like so: * * |[ * /* Create an actor out of a PLY model file */ * ClutterActor *model * = mash_model_new_from_file ("some-model.ply", NULL); - * /* Get a handle to the default material for the actor */ - * CoglHandle material - * = mash_model_get_material (MASH_MODEL (model)); + * /* Get a handle to the default pipeline for the actor */ + * CoglHandle pipeline + * = mash_model_get_pipeline (MASH_MODEL (model)); * /* Load a texture image from a file */ * CoglHandle texture * = cogl_texture_new_from_file ("some-image.png", COGL_TEXTURE_NONE, * COGL_PIXEL_FORMAT_ANY, NULL); - * /* Set a texture layer on the material */ - * cogl_material_set_layer (material, 0, texture); - * /* The texture is now referenced by the material so we can + * /* Set a texture layer on the pipeline */ + * cogl_pipeline_set_layer (pipeline, 0, texture); + * /* The texture is now referenced by the pipeline so we can * drop the reference we have */ * cogl_handle_unref (texture); * ]| @@ -71,6 +71,10 @@ #include #endif +#define CLUTTER_ENABLE_EXPERIMENTAL_API +#define COGL_ENABLE_EXPERIMENTAL_API + + #include #include #include @@ -118,7 +122,8 @@ struct _MashModelPrivate { MashData *data; MashLightSet *light_set; - CoglHandle material, pick_material; + CoglPipeline *pipeline, *pick_pipeline; + CoglFramebuffer *fb; /* Whether the model should be transformed to fill the allocation */ gboolean fit_to_allocation; /* The amount to scale (on all axes) when fit_to_allocation is @@ -127,13 +132,15 @@ struct _MashModelPrivate /* Translation used when fit_to_allocation is TRUE. This is calculated in the allocate method */ gfloat translate_x, translate_y, translate_z; + gfloat progress; + gboolean pipeline_created; }; enum { PROP_0, - PROP_MATERIAL, + PROP_PIPELINE, PROP_DATA, PROP_LIGHT_SET, PROP_FIT_TO_ALLOCATION @@ -151,20 +158,20 @@ mash_model_class_init (MashModelClass *klass) gobject_class->set_property = mash_model_set_property; actor_class->paint = mash_model_paint; - actor_class->pick = mash_model_pick; + //actor_class->pick = mash_model_pick; actor_class->get_preferred_width = mash_model_get_preferred_width; actor_class->get_preferred_height = mash_model_get_preferred_height; actor_class->allocate = mash_model_allocate; - pspec = g_param_spec_boxed ("material", - "Material", - "The Cogl material to render with", + pspec = g_param_spec_boxed ("pipeline", + "pipeline", + "The Cogl pipeline to render with", COGL_TYPE_HANDLE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); - g_object_class_install_property (gobject_class, PROP_MATERIAL, pspec); + g_object_class_install_property (gobject_class, PROP_PIPELINE, pspec); pspec = g_param_spec_object ("data", "Data", @@ -209,10 +216,22 @@ mash_model_init (MashModel *self) priv = self->priv = MASH_MODEL_GET_PRIVATE (self); - /* Default to a plain white material */ - priv->material = cogl_material_new (); + /* Default to a plain white pipeline */ + + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + priv->pipeline = cogl_pipeline_new (ctx); + priv->pick_pipeline = cogl_pipeline_new (ctx); priv->fit_to_allocation = TRUE; + priv->progress = -1; + + g_signal_connect_swapped (self, "paint", + G_CALLBACK (cogl_set_depth_test_enabled), + GINT_TO_POINTER (TRUE)); + g_signal_connect_data (self, "paint", + G_CALLBACK (cogl_set_depth_test_enabled), + GINT_TO_POINTER (FALSE), NULL, + G_CONNECT_AFTER | G_CONNECT_SWAPPED); } /** @@ -242,10 +261,10 @@ mash_model_new (void) * This is a convenience function that creates a new #MashData * and immediately loads the data in @filename. If the load succeeds a * new #MashModel will be created for the data. The model has a - * default white material so that if vertices of the model have any - * color attributes they will be used directly. The material does not + * default white pipeline so that if vertices of the model have any + * color attributes they will be used directly. The pipeline does not * have textures by default so if you want the model to be textured - * you will need to modify the material. + * you will need to modify the pipeline. * * Return value: a new #MashModel or %NULL if the load failed. */ @@ -275,12 +294,12 @@ mash_model_dispose (GObject *object) MashModelPrivate *priv = self->priv; mash_model_set_data (self, NULL); - mash_model_set_material (self, COGL_INVALID_HANDLE); + mash_model_set_pipeline (self, COGL_INVALID_HANDLE); - if (priv->pick_material) + if (priv->pick_pipeline) { - cogl_handle_unref (priv->pick_material); - priv->pick_material = COGL_INVALID_HANDLE; + cogl_handle_unref (priv->pick_pipeline); + priv->pick_pipeline = COGL_INVALID_HANDLE; } mash_model_set_light_set (self, NULL); @@ -289,112 +308,124 @@ mash_model_dispose (GObject *object) } /** - * mash_model_set_material: + * mash_model_set_pipeline: * @self: A #MashModel instance - * @material: A handle to a Cogl material + * @pipeline: A handle to a Cogl pipeline * - * Replaces the material that will be used to render the model with + * Replaces the pipeline that will be used to render the model with * the given one. By default a #MashModel will use a solid white - * material. However the color of the material is still blended with - * the vertex colors so the white material will cause the vertex + * pipeline. However the color of the pipeline is still blended with + * the vertex colors so the white pipeline will cause the vertex * colors to be used directly. If you want the model to be textured - * you will need to create a material that has a texture layer and set + * you will need to create a pipeline that has a texture layer and set * it with this function. * - * If a #MashLightSet is used with the model then the material given + * If a #MashLightSet is used with the model then the pipeline given * here will be modified to use the program generated by that light - * set. If multiple models are expected to use the same material with + * set. If multiple models are expected to use the same pipeline with * different light sets, it would be better to use a different copy of - * the same material for each set of models so that they don't - * repeatedly change the program on the material during paint. + * the same pipeline for each set of models so that they don't + * repeatedly change the program on the pipeline during paint. */ void -mash_model_set_material (MashModel *self, - CoglHandle material) +mash_model_set_pipeline (MashModel *self, + CoglPipeline* pipeline) { MashModelPrivate *priv; + //fprintf(stderr, "mash_model_set_pipeline\n"); + g_return_if_fail (MASH_IS_MODEL (self)); - g_return_if_fail (material == COGL_INVALID_HANDLE - || cogl_is_material (material)); + g_return_if_fail (pipeline == COGL_INVALID_HANDLE + || cogl_is_pipeline (pipeline)); + priv = self->priv; - if (material) - cogl_handle_ref (material); + if (pipeline) + cogl_handle_ref (pipeline); - if (priv->material) - cogl_handle_unref (priv->material); + if (priv->pipeline) + cogl_handle_unref (priv->pipeline); - priv->material = material; + priv->pipeline = pipeline; clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); - g_object_notify (G_OBJECT (self), "material"); + g_object_notify (G_OBJECT (self), "pipeline"); } /** - * mash_model_get_material: + * mash_model_get_pipeline: * @self: A #MashModel instance * - * Gets the material that will be used to render the model. The - * material can be modified to affect the appearence of the model. By - * default the material will be solid white. + * Gets the pipeline that will be used to render the model. The + * pipeline can be modified to affect the appearence of the model. By + * default the pipeline will be solid white. * - * Return value: a handle to the Cogl material used by the model. + * Return value: a handle to the Cogl pipeline used by the model. */ -CoglHandle -mash_model_get_material (MashModel *self) +CoglPipeline* +mash_model_get_pipeline (MashModel *self) { g_return_val_if_fail (MASH_IS_MODEL (self), COGL_INVALID_HANDLE); - return self->priv->material; + return self->priv->pipeline; } static void mash_model_render_data (MashModel *self) { MashModelPrivate *priv = self->priv; + priv->fb = cogl_get_draw_framebuffer(); if (priv->fit_to_allocation) { - cogl_push_matrix (); + cogl_framebuffer_push_matrix (priv->fb); - cogl_translate (priv->translate_x, + cogl_framebuffer_translate (priv->fb, + priv->translate_x, priv->translate_y, priv->translate_z); - cogl_scale (priv->scale, priv->scale, priv->scale); + cogl_framebuffer_scale (priv->fb, priv->scale, priv->scale, priv->scale); } - mash_data_render (priv->data); + mash_data_render (priv->data, (CoglPipeline *) priv->pipeline); if (priv->fit_to_allocation) - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (priv->fb); } static void -mash_model_paint (ClutterActor *actor) -{ +mash_model_paint (ClutterActor *actor){ MashModel *self = MASH_MODEL (actor); MashModelPrivate *priv; g_return_if_fail (MASH_IS_MODEL (self)); priv = self->priv; + priv->fb = cogl_get_draw_framebuffer(); - /* Silently fail if we haven't got any data or a material */ - if (priv->data == NULL || priv->material == COGL_INVALID_HANDLE) + /* Silently fail if we haven't got any data or a pipeline */ + if (priv->data == NULL || priv->pipeline == COGL_INVALID_HANDLE) return; - if (priv->light_set) - { - CoglHandle program = mash_light_set_begin_paint (priv->light_set, - priv->material); - cogl_material_set_user_program (priv->material, program); - } - - cogl_set_source (priv->material); + if(!cogl_is_pipeline(priv->pipeline)) + return; + if (priv->light_set){ + if(mash_light_set_update_layer_indices(priv->light_set, priv->pipeline)){ + // Recreate program + priv->pipeline_created = FALSE; + } + if(!priv->pipeline_created){ + mash_light_set_get_pipeline (priv->light_set, priv->pipeline); + priv->pipeline_created = TRUE; + } + mash_light_set_begin_paint(priv->light_set, priv->pipeline); + } + + /* Now we can render with the snippet as usual */ mash_model_render_data (self); } @@ -405,20 +436,18 @@ mash_model_pick (ClutterActor *actor, MashModel *self = MASH_MODEL (actor); MashModelPrivate *priv; CoglColor color; - g_return_if_fail (MASH_IS_MODEL (self)); priv = self->priv; /* Silently fail if we haven't got any data */ - if (priv->data == NULL) + if (priv->data == NULL){ return; - - if (priv->pick_material == COGL_INVALID_HANDLE) - { + } + + if (priv->pick_pipeline == COGL_INVALID_HANDLE){ GError *error = NULL; - priv->pick_material = cogl_material_new (); - if (!cogl_material_set_layer_combine (priv->pick_material, 0, + if (!cogl_pipeline_set_layer_combine (priv->pick_pipeline, 0, "RGBA=REPLACE(CONSTANT)", &error)) { @@ -427,15 +456,13 @@ mash_model_pick (ClutterActor *actor, } } - cogl_color_set_from_4ub (&color, + cogl_color_init_from_4ub (&color, pick_color->red, pick_color->green, pick_color->blue, 255); - cogl_material_set_layer_combine_constant (priv->pick_material, 0, &color); - - cogl_set_source (priv->pick_material); - + cogl_pipeline_set_layer_combine_constant (priv->pick_pipeline, 0, &color); + //cogl_set_source (priv->pick_pipeline); mash_model_render_data (self); } @@ -537,8 +564,8 @@ mash_model_set_light_set (MashModel *self, priv->light_set = light_set; - if (light_set == NULL && priv->material) - cogl_material_set_user_program (priv->material, COGL_INVALID_HANDLE); + //if (light_set == NULL && priv->pipeline) + // cogl_pipeline_set_user_program (priv->pipeline, COGL_INVALID_HANDLE); clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); @@ -618,8 +645,8 @@ mash_model_get_property (GObject *object, switch (prop_id) { - case PROP_MATERIAL: - g_value_set_boxed (value, mash_model_get_material (model)); + case PROP_PIPELINE: + g_value_set_boxed (value, mash_model_get_pipeline (model)); break; case PROP_DATA: @@ -651,8 +678,8 @@ mash_model_set_property (GObject *object, switch (prop_id) { - case PROP_MATERIAL: - mash_model_set_material (model, g_value_get_boxed (value)); + case PROP_PIPELINE: + mash_model_set_pipeline (model, g_value_get_boxed (value)); break; case PROP_DATA: @@ -674,6 +701,7 @@ mash_model_set_property (GObject *object, } } + static void mash_model_get_preferred_width (ClutterActor *actor, gfloat for_height, @@ -815,3 +843,105 @@ mash_model_allocate (ClutterActor *actor, priv->translate_z = -(min_vertex.z + max_vertex.z) / 2.0f * min_scale; } } + + +/** + * mash_model_set_color: + * @self: a #ToggleModel + * @color: the #ClutterColor to use as the color for the button text + * + * Set the color of the model when finished + */ +void +mash_model_set_color (MashModel *self, const ClutterColor *color){ + MashModelPrivate *priv; + + g_return_if_fail (MASH_IS_MODEL (self)); + + priv = self->priv; + CoglColor *c = cogl_color_new(); + cogl_color_init_from_4ub(c, color->red, color->green, color->blue, color->alpha); + cogl_pipeline_set_layer_combine_constant (priv->pipeline, 0, c); + cogl_pipeline_set_layer_combine (priv->pipeline, 0, "RGBA = MODULATE (CONSTANT, PRIMARY)", NULL); + +} + + +/** + * masg_model_set_progress: + * @self: a #MashModel + * @progress: the progress finished as #float from 0 to 1 + * + * Set the progress for the model + */ +void +mash_model_set_progress (MashModel *self, float progress){ + MashModelPrivate *priv; + + g_return_if_fail (MASH_IS_MODEL (self)); + priv = self->priv; + + if(priv->progress == -1){ + int prog = cogl_pipeline_get_uniform_location (priv->pipeline, "progress"); + //fprintf(stderr, "Progress: %i\n", prog); + + CoglSnippet *snippet_v; + snippet_v = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS, + "varying vec4 vertex_pos;\n", + NULL); + + /* Add it to the pipeline */ + cogl_pipeline_add_snippet (priv->pipeline, snippet_v); + /* The pipeline keeps a reference to the snippet + so we don't need to */ + cogl_object_unref (snippet_v); + + CoglSnippet *snippet_v2 = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, + NULL, + "vertex_pos = cogl_position_in;\n"); + + /* Add it to the pipeline */ + cogl_pipeline_add_snippet (priv->pipeline, snippet_v2); + /* The pipeline keeps a reference to the snippet + so we don't need to */ + cogl_object_unref (snippet_v2); + + CoglSnippet *snippet; + // TODO: Allow user defined color + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + "uniform float progress;\n" + "varying vec4 vertex_pos;\n", + "if(progress < vertex_pos.z){\n" + " cogl_color_out.a = 0.5;\n" + "}\n"); + + /* Add it to the pipeline */ + cogl_pipeline_add_snippet (priv->pipeline, snippet); + /* The pipeline keeps a reference to the snippet + so we don't need to */ + cogl_object_unref (snippet); + } + + priv->progress = progress; + + /* Update the custom uniform on the pipeline */ + int prog = cogl_pipeline_get_uniform_location (priv->pipeline, "progress"); + cogl_pipeline_set_uniform_1f (priv->pipeline, prog, progress); +} + + +/** + * mash_model_set_culling: + * @self: a #ToggleModel + * @culling: the culling type + * + * Set the culling type for the model + */ +void +mash_model_set_culling (MashModel *self, int culling){ + g_return_if_fail (MASH_IS_MODEL (self)); + cogl_pipeline_set_cull_face_mode (self->priv->pipeline, culling); +} + + + diff --git a/mash/mash-model.h b/mash/mash-model.h index ea1a40f..cedd263 100644 --- a/mash/mash-model.h +++ b/mash/mash-model.h @@ -87,9 +87,9 @@ ClutterActor *mash_model_new_from_file (MashDataFlags flags, const gchar *filename, GError **error); -CoglHandle mash_model_get_material (MashModel *self); -void mash_model_set_material (MashModel *self, - CoglHandle material); +CoglPipeline* mash_model_get_pipeline (MashModel *self); +void mash_model_set_pipeline (MashModel *self, + CoglPipeline *pipeline); MashData *mash_model_get_data (MashModel *self); void mash_model_set_data (MashModel *self, @@ -103,6 +103,16 @@ gboolean mash_model_get_fit_to_allocation (MashModel *self); void mash_model_set_fit_to_allocation (MashModel *self, gboolean fit_to_allocation); + +void +mash_model_set_color (MashModel *self, const ClutterColor *color); + +void +mash_model_set_progress (MashModel *self, float progress); + +void +mash_model_set_culling (MashModel *self, int culling); + G_END_DECLS #endif /* __MASH_MODEL_H__ */ diff --git a/mash/mash-point-light.c b/mash/mash-point-light.c index 5f5d574..05dcf0b 100644 --- a/mash/mash-point-light.c +++ b/mash/mash-point-light.c @@ -42,6 +42,9 @@ #include #endif +#define CLUTTER_ENABLE_EXPERIMENTAL_API +#define COGL_ENABLE_EXPERIMENTAL_API + #include #include "mash-light.h" @@ -60,7 +63,7 @@ static void mash_point_light_generate_shader (MashLight *light, GString *uniform_source, GString *main_source); static void mash_point_light_update_uniforms (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); G_DEFINE_TYPE (MashPointLight, mash_point_light, MASH_TYPE_LIGHT); @@ -455,7 +458,7 @@ mash_point_light_generate_shader (MashLight *light, static void mash_point_light_update_uniforms (MashLight *light, - CoglHandle program) + CoglPipeline *pipeline) { MashPointLight *plight = MASH_POINT_LIGHT (light); MashPointLightPrivate *priv = plight->priv; @@ -463,20 +466,20 @@ mash_point_light_update_uniforms (MashLight *light, CoglMatrix matrix; MASH_LIGHT_CLASS (mash_point_light_parent_class) - ->update_uniforms (light, program); + ->update_uniforms (light, pipeline); if (priv->uniform_locations_dirty) { priv->attenuation_uniform_location - = mash_light_get_uniform_location (light, program, "attenuation"); + = mash_light_get_uniform_location (light, pipeline, "attenuation"); priv->light_eye_coord_uniform_location - = mash_light_get_uniform_location (light, program, "light_eye_coord"); + = mash_light_get_uniform_location (light, pipeline, "light_eye_coord"); priv->uniform_locations_dirty = FALSE; } if (priv->attenuation_dirty) { - cogl_program_set_uniform_float (program, + cogl_pipeline_set_uniform_float (pipeline, priv->attenuation_uniform_location, 3, 1, priv->attenuation); @@ -500,7 +503,7 @@ mash_point_light_update_uniforms (MashLight *light, light_eye_coord[1] /= light_eye_coord[3]; light_eye_coord[2] /= light_eye_coord[3]; - cogl_program_set_uniform_float (program, + cogl_pipeline_set_uniform_float (pipeline, priv->light_eye_coord_uniform_location, 3, 1, light_eye_coord); diff --git a/mash/mash-spot-light.c b/mash/mash-spot-light.c index 0e23f30..e9390ff 100644 --- a/mash/mash-spot-light.c +++ b/mash/mash-spot-light.c @@ -59,7 +59,7 @@ static void mash_spot_light_generate_shader (MashLight *light, GString *uniform_source, GString *main_source); static void mash_spot_light_update_uniforms (MashLight *light, - CoglHandle program); + CoglPipeline *pipeline); G_DEFINE_TYPE (MashSpotLight, mash_spot_light, MASH_TYPE_POINT_LIGHT); @@ -399,7 +399,7 @@ mash_spot_light_generate_shader (MashLight *light, static void mash_spot_light_update_uniforms (MashLight *light, - CoglHandle program) + CoglPipeline *pipeline) { MashSpotLight *slight = MASH_SPOT_LIGHT (light); MashSpotLightPrivate *priv = slight->priv; @@ -408,25 +408,25 @@ mash_spot_light_update_uniforms (MashLight *light, static const float light_direction[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; MASH_LIGHT_CLASS (mash_spot_light_parent_class) - ->update_uniforms (light, program); + ->update_uniforms (light, pipeline); if (priv->uniform_locations_dirty) { priv->spot_cos_cutoff_uniform_location - = mash_light_get_uniform_location (light, program, "spot_cos_cutoff"); + = mash_light_get_uniform_location (light, pipeline, "spot_cos_cutoff"); priv->spot_exponent_uniform_location - = mash_light_get_uniform_location (light, program, "spot_exponent"); + = mash_light_get_uniform_location (light, pipeline, "spot_exponent"); priv->light_direction_uniform_location - = mash_light_get_uniform_location (light, program, "spot_direction"); + = mash_light_get_uniform_location (light, pipeline, "spot_direction"); priv->uniform_locations_dirty = FALSE; } if (priv->spot_params_dirty) { - cogl_program_set_uniform_1f (program, + cogl_pipeline_set_uniform_1f (pipeline, priv->spot_cos_cutoff_uniform_location, cosf (priv->spot_cutoff * G_PI / 180.0)); - cogl_program_set_uniform_1f (program, + cogl_pipeline_set_uniform_1f (pipeline, priv->spot_exponent_uniform_location, priv->spot_exponent); priv->spot_params_dirty = FALSE; @@ -439,7 +439,7 @@ mash_spot_light_update_uniforms (MashLight *light, allocation */ mash_light_set_direction_uniform (light, - program, + pipeline, priv->light_direction_uniform_location, light_direction); } diff --git a/mash/mash-stl-loader.c b/mash/mash-stl-loader.c new file mode 100644 index 0000000..20bfcbc --- /dev/null +++ b/mash/mash-stl-loader.c @@ -0,0 +1,478 @@ +/* + * Mash - A library for displaying STL models in a Clutter scene + * Copyright (C) 2010 Intel Corporation + * Copyright (C) 2010 Luca Bruno + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define CLUTTER_ENABLE_EXPERIMENTAL_API +#define COGL_ENABLE_EXPERIMENTAL_API + +#include +#include +#include +#include + +#include "mash-stl-loader.h" +#include "rstl/rstl.h" + +static void mash_stl_loader_finalize (GObject *object); +static gboolean mash_stl_loader_load (MashDataLoader *data_loader, + MashDataFlags flags, + const gchar *filename, + GError **error); +static void mash_stl_loader_get_data (MashDataLoader *data_loader, + MashDataLoaderData *loader_data); + +G_DEFINE_TYPE (MashStlLoader, mash_stl_loader, MASH_TYPE_DATA_LOADER); + +#define MASH_STL_LOADER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MASH_TYPE_STL_LOADER, \ + MashStlLoaderPrivate)) + +static const struct +{ + const gchar *name; + int size; +} +mash_stl_loader_properties[] = +{ + /* These should be sorted in descending order of size so that it + never ends doing an unaligned write */ + { "nx", sizeof (gfloat) }, + { "ny", sizeof (gfloat) }, + { "nz", sizeof (gfloat) }, + { "x0", sizeof (gfloat) }, + { "y0", sizeof (gfloat) }, + { "z0", sizeof (gfloat) }, + { "x1", sizeof (gfloat) }, + { "y1", sizeof (gfloat) }, + { "z1", sizeof (gfloat) }, + { "x2", sizeof (gfloat) }, + { "y2", sizeof (gfloat) }, + { "z2", sizeof (gfloat) }, +}; + +#define MASH_STL_LOADER_VERTEX_PROPS 511 +//#define MASH_STL_LOADER_NORMAL_PROPS (7 << 3) +//#define MASH_STL_LOADER_TEX_COORD_PROPS (3 << 6) +//#define MASH_STL_LOADER_COLOR_PROPS (7 << 8) + +typedef struct _MashStlLoaderData MashStlLoaderData; + +struct _MashStlLoaderData{ + p_stl stl; + GError *error; + /* Data for the current vertex */ + guint8 current_vertex[G_N_ELEMENTS (mash_stl_loader_properties) * 4]; + /* Map from property number to byte offset in the current_vertex array */ + gint prop_map[G_N_ELEMENTS (mash_stl_loader_properties)]; + /* Number of bytes for a vertex */ + guint n_vertex_bytes; + gint available_props, got_props; + guint first_vertex, last_vertex; + GByteArray *vertices; + GArray *faces; + CoglIndicesType indices_type; + MashDataFlags flags; + + /* Bounding cuboid of the data */ + ClutterVertex min_vertex, max_vertex; + + /* Range of indices used */ + guint min_index, max_index; + + CoglContext *ctx; + CoglPrimitive *prim; +}; + +struct _MashStlLoaderPrivate{ + CoglHandle vertices_vbo; + CoglHandle indices; + guint min_index, max_index; + guint n_triangles; + + /* Bounding cuboid of the data */ + ClutterVertex min_vertex, max_vertex; + CoglPrimitive *prim; +}; + +static void +mash_stl_loader_class_init (MashStlLoaderClass *klass){ + GObjectClass *gobject_class = (GObjectClass *) klass; + MashDataLoaderClass *data_loader_class = (MashDataLoaderClass *) klass; + + gobject_class->finalize = mash_stl_loader_finalize; + + data_loader_class->load = mash_stl_loader_load; + data_loader_class->get_data = mash_stl_loader_get_data; + + g_type_class_add_private (klass, sizeof (MashStlLoaderPrivate)); +} + +static void +mash_stl_loader_init (MashStlLoader *self){ + self->priv = MASH_STL_LOADER_GET_PRIVATE (self); +} + +static void +mash_stl_loader_free_vbos (MashStlLoader *self){ + MashStlLoaderPrivate *priv = self->priv; + + if (priv->vertices_vbo) + { + cogl_handle_unref (priv->vertices_vbo); + priv->vertices_vbo = NULL; + } + + if (priv->indices) + { + cogl_handle_unref (priv->indices); + priv->indices = NULL; + } +} + +static void +mash_stl_loader_finalize (GObject *object){ + MashStlLoader *self = (MashStlLoader *) object; + + mash_stl_loader_free_vbos (self); + + G_OBJECT_CLASS (mash_stl_loader_parent_class)->finalize (object); +} + +static void +mash_stl_loader_error_cb (const char *message, gpointer data){ + MashStlLoaderData *load_stl_loader = data; + + if (load_stl_loader->error == NULL) + g_set_error_literal (&load_stl_loader->error, MASH_DATA_ERROR, + MASH_DATA_ERROR_UNKNOWN, message); +} + +static void +mash_stl_loader_check_unknown_error (MashStlLoaderData *data){ + if (data->error == NULL) + g_set_error_literal (&data->error, + MASH_DATA_ERROR, + MASH_DATA_ERROR_UNKNOWN, + "Unknown error loading STL file"); +} + +static int +mash_stl_loader_vertex_read_cb (p_stl_argument argument){ + long prop_num; + MashStlLoaderData *data; + gint32 length, index; + double value; + + stl_get_argument_user_data (argument, (void **) &data, &prop_num); + stl_get_argument_property (argument, NULL, &length, &index); + + + if (length != 1 || index != 0){ + g_set_error (&data->error, MASH_DATA_ERROR, + MASH_DATA_ERROR_INVALID, + "List type property not supported for vertex element '%s'", + mash_stl_loader_properties[prop_num].name); + + return 0; + } + + + value = stl_get_argument_value (argument); + //fprintf(stderr, "mash_stl_loader_vertex_read_cb(), value = %f\n", value); + + *(gfloat *) (data->current_vertex + data->prop_map[prop_num]) = value; + + data->got_props |= 1 << prop_num; + + /* If we've got enough properties for a complete vertex then add it + to the array */ + if (data->got_props == data->available_props){ + int i, j; + if( (*(gfloat *) (data->current_vertex + data->prop_map[0]) == 0.0) && + (*(gfloat *) (data->current_vertex + data->prop_map[1]) == 0.0) && + (*(gfloat *) (data->current_vertex + data->prop_map[2]) == 0.0)){ + // No normal data in the STL. Calculate it + //fprintf(stderr, "Missing normal data\n"); + + float u1[3], u2[3], cross[3]; + float v1[3], v2[3], v3[3]; + + cogl_vector3_init (v1, + *(gfloat *) (data->current_vertex + data->prop_map[3]), + *(gfloat *) (data->current_vertex + data->prop_map[4]), + *(gfloat *) (data->current_vertex + data->prop_map[5])); + cogl_vector3_init (v2, + *(gfloat *) (data->current_vertex + data->prop_map[6]), + *(gfloat *) (data->current_vertex + data->prop_map[7]), + *(gfloat *) (data->current_vertex + data->prop_map[8])); + cogl_vector3_init (v3, + *(gfloat *) (data->current_vertex + data->prop_map[9]), + *(gfloat *) (data->current_vertex + data->prop_map[10]), + *(gfloat *) (data->current_vertex + data->prop_map[11])); + + //fprintf(stderr, "V1: %f, %f, %f\n", v1[0], v1[1], v1[2]); + //fprintf(stderr, "V2: %f, %f, %f\n", v2[0], v2[1], v2[2]); + //fprintf(stderr, "V3: %f, %f, %f\n", v3[0], v3[1], v3[2]); + + cogl_vector3_init_zero(u1); + cogl_vector3_init_zero(u2); + + cogl_vector3_subtract(u1, v1, v2); + cogl_vector3_subtract(u2, v2, v3); + + //fprintf(stderr, "U1: %f, %f, %f\n", u1[0], u1[1], u1[2]); + //fprintf(stderr, "U2: %f, %f, %f\n", u2[0], u2[1], u2[2]); + + cogl_vector3_subtract(u2, v2, v3); + cogl_vector3_cross_product(cross, u1, u2); + cogl_vector3_normalize(cross); + //fprintf(stderr, "New normal: %f, %f, %f\n", cross[0], cross[1], cross[2]); + *(gfloat *) (data->current_vertex + data->prop_map[0]) = cross[0]; + *(gfloat *) (data->current_vertex + data->prop_map[1]) = cross[1]; + *(gfloat *) (data->current_vertex + data->prop_map[2]) = cross[2]; + } + + for(i=0; i<3; i++){ + // Append first vertex data + g_byte_array_append (data->vertices, data->current_vertex + data->prop_map[3+i*3], + mash_stl_loader_properties[3].size*3); + // Append the normal data. This is the same for all vertices + g_byte_array_append (data->vertices, data->current_vertex + data->prop_map[0], + mash_stl_loader_properties[0].size*3); + } + data->got_props = 0; + /* Update the bounding box for the data + TODO: This should only have to be done once, not for every vertex.*/ + for (i = 0; i < 3; i++){ + for(j=0; j<3; j++){ + gfloat *min = &data->min_vertex.x + j; + gfloat *max = &data->max_vertex.x + j; + gfloat value = *(gfloat *) (data->current_vertex + data->prop_map[3+i*3+j]); + //fprintf(stderr, "value = %f, min_x = %f, max_x = %f\n", value, *min, *max); + if (value < *min) + *min = value; + if (value > *max) + *max = value; + } + } + } + + return 1; +} + + +static gboolean +mash_stl_loader_get_indices_type (MashStlLoaderData *data, + GError **error){ + p_stl_element elem = NULL; + + ClutterBackend *be = clutter_get_default_backend (); + CoglContext *ctx = (CoglContext*) clutter_backend_get_cogl_context (be); + + /* Look for the 'vertices' element */ + while ((elem = stl_get_next_element (data->stl, elem))){ + const char *name; + gint32 n_instances; + if (stl_get_element_info (elem, &name, &n_instances)){ + if (!strcmp (name, "facet")){ + if (n_instances <= 0x100){ + data->indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE; + data->faces = g_array_new (FALSE, FALSE, sizeof (guint8)); + } + else if (n_instances <= 0x10000){ + data->indices_type = COGL_INDICES_TYPE_UNSIGNED_SHORT; + data->faces = g_array_new (FALSE, FALSE, sizeof (guint16)); + } + else if (cogl_has_feature(ctx, COGL_FEATURE_UNSIGNED_INT_INDICES)){ + data->indices_type = COGL_INDICES_TYPE_UNSIGNED_INT; + data->faces = g_array_new (FALSE, FALSE, sizeof (guint32)); + } + else{ + g_set_error (error, MASH_DATA_ERROR, + MASH_DATA_ERROR_UNSUPPORTED, + "The STL file requires unsigned int indices " + "but this is not supported by your GL driver"); + return FALSE; + } + return TRUE; + } + } + else{ + g_set_error (error, MASH_DATA_ERROR, + MASH_DATA_ERROR_UNKNOWN, + "Error getting element info"); + return FALSE; + } + } + + g_set_error (error, MASH_DATA_ERROR, + MASH_DATA_ERROR_MISSING_PROPERTY, + "STL file is missing the vertex element"); + + return FALSE; +} + +static gboolean +mash_stl_loader_load (MashDataLoader *data_loader, + MashDataFlags flags, + const gchar *filename, + GError **error){ + MashStlLoader *self = MASH_STL_LOADER (data_loader); + MashStlLoaderPrivate *priv; + MashStlLoaderData data; + gchar *display_name; + gboolean ret; + + int i,j; + + priv = self->priv; + + data.error = NULL; + data.n_vertex_bytes = 0; + data.available_props = 0; + data.got_props = 0; + data.vertices = g_byte_array_new (); + data.faces = NULL; + data.min_vertex.x = G_MAXFLOAT; + data.min_vertex.y = G_MAXFLOAT; + data.min_vertex.z = G_MAXFLOAT; + data.max_vertex.x = -G_MAXFLOAT; + data.max_vertex.y = -G_MAXFLOAT; + data.max_vertex.z = -G_MAXFLOAT; + data.min_index = G_MAXUINT; + data.max_index = 0; + data.flags = flags; + + display_name = g_filename_display_name (filename); + + + + if ((data.stl = stl_open (filename, + mash_stl_loader_error_cb, + &data)) == NULL) + mash_stl_loader_check_unknown_error (&data); + else{ + //fprintf(stderr, "STL open OK\n"); + if (!stl_read_header (data.stl)) + mash_stl_loader_check_unknown_error (&data); + else{ + //fprintf(stderr, "STL header read OK\n"); + int i; + for (i = 0; i < G_N_ELEMENTS (mash_stl_loader_properties); i++){ + if (stl_set_read_cb (data.stl, "facet", + mash_stl_loader_properties[i].name, + mash_stl_loader_vertex_read_cb, + &data, i)){ + data.prop_map[i] = data.n_vertex_bytes; + data.n_vertex_bytes += mash_stl_loader_properties[i].size; + data.available_props |= 1 << i; + } + } + //fprintf(stderr, "STL aligning\n"); + /* Align the size of a vertex to 32 bits */ + data.n_vertex_bytes = (data.n_vertex_bytes + 3) & ~(guint) 3; + if ((data.available_props & MASH_STL_LOADER_VERTEX_PROPS) + != MASH_STL_LOADER_VERTEX_PROPS) + g_set_error (&data.error, MASH_DATA_ERROR, + MASH_DATA_ERROR_MISSING_PROPERTY, + "STL file %s is missing the vertex properties", + display_name); + //fprintf(stderr, "STL getting indices\n"); + if (mash_stl_loader_get_indices_type (&data, &data.error) + && !stl_read (data.stl)) + mash_stl_loader_check_unknown_error (&data); + } + stl_close (data.stl); + } + if (data.error){ + g_propagate_error (error, data.error); + ret = FALSE; + } + else{ + /* Make sure all of the indices are valid */ + if (data.max_index >= data.vertices->len / data.n_vertex_bytes){ + g_set_error (error, MASH_DATA_ERROR, + MASH_DATA_ERROR_INVALID, + "Index out of range in %s", + display_name); + ret = FALSE; + } + else{ + ClutterBackend *be = clutter_get_default_backend (); + CoglContext *ctx = (CoglContext*) clutter_backend_get_cogl_context (be); + + data.n_vertex_bytes = sizeof (float) *6; + + int nr_vertices = data.vertices->len/(sizeof (float)*6); + + CoglAttributeBuffer *buffer = cogl_attribute_buffer_new (ctx, data.vertices->len, data.vertices->data); + CoglAttribute *attributes[2]; + attributes[0] = cogl_attribute_new (buffer, + "cogl_position_in", + /* Stride */ + sizeof (float) * 6, + /* Offset */ + 0, + /* n_components */ + 3, + COGL_ATTRIBUTE_TYPE_FLOAT); + attributes[1] = cogl_attribute_new (buffer, + "cogl_normal_in", + /* Stride */ + sizeof (float) * 6, + /* Offset */ + sizeof (float) * 3, + /* n_components */ + 3, + COGL_ATTRIBUTE_TYPE_FLOAT); + priv->prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES, + nr_vertices, /* n_vertices */ + attributes, + 2 /* n_attributes */); + cogl_object_unref (attributes[0]); + cogl_object_unref (attributes[1]); + cogl_object_unref (buffer); + + priv->min_vertex = data.min_vertex; + priv->max_vertex = data.max_vertex; + ret = TRUE; + } + } + + g_free (display_name); + g_byte_array_free (data.vertices, TRUE); + if (data.faces) + g_array_free (data.faces, TRUE); + + return ret; +} + +static void +mash_stl_loader_get_data (MashDataLoader *data_loader, MashDataLoaderData *loader_data){ + MashStlLoader *self = MASH_STL_LOADER (data_loader); + MashStlLoaderPrivate *priv = self->priv; + + loader_data->min_vertex = priv->min_vertex; + loader_data->max_vertex = priv->max_vertex; + + loader_data->prim = priv->prim; +} diff --git a/mash/mash-stl-loader.h b/mash/mash-stl-loader.h new file mode 100644 index 0000000..15af17c --- /dev/null +++ b/mash/mash-stl-loader.h @@ -0,0 +1,74 @@ +/* + * Mash - A library for displaying STL models in a Clutter scene + * Copyright (C) 2010 Intel Corporation + * Copyright (C) 2010 Luca Bruno + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#if !defined(__MASH_H_INSIDE__) && !defined(MASH_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __MASH_STL_LOADER_H__ +#define __MASH_STL_LOADER_H__ + +#include "mash-data-loader.h" + +G_BEGIN_DECLS + +#define MASH_TYPE_STL_LOADER \ + (mash_stl_loader_get_type()) +#define MASH_STL_LOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + MASH_TYPE_STL_LOADER, \ + MashStlLoader)) +#define MASH_STL_LOADER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + MASH_TYPE_STL_LOADER, \ + MashStlLoaderClass)) +#define MASH_IS_STL_LOADER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + MASH_TYPE_STL_LOADER)) +#define MASH_IS_STL_LOADER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + MASH_TYPE_STL_LOADER)) +#define MASH_STL_LOADER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + MASH_TYPE_STL_LOADER, \ + MashStlLoaderClass)) + +typedef struct _MashStlLoader MashStlLoader; +typedef struct _MashStlLoaderClass MashStlLoaderClass; +typedef struct _MashStlLoaderPrivate MashStlLoaderPrivate; + +struct _MashStlLoaderClass +{ + /*< private >*/ + MashDataLoaderClass parent_class; +}; + +struct _MashStlLoader +{ + /*< private >*/ + GObject parent; + + MashStlLoaderPrivate *priv; +}; + +GType mash_stl_loader_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __MASH_STL_LOADER_H__ */ diff --git a/mash/rstl/LICENSE b/mash/rstl/LICENSE new file mode 100644 index 0000000..02e7c5f --- /dev/null +++ b/mash/rstl/LICENSE @@ -0,0 +1,20 @@ +RPly 1.01 license +Copyright � 2003-2005 Diego Nehab. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/mash/rstl/Makefile b/mash/rstl/Makefile new file mode 100644 index 0000000..982af74 --- /dev/null +++ b/mash/rstl/Makefile @@ -0,0 +1,621 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# mash/rstl/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/mash +pkgincludedir = $(includedir)/mash +pkglibdir = $(libdir)/mash +pkglibexecdir = $(libexecdir)/mash +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-pc-linux-gnu +host_triplet = x86_64-pc-linux-gnu +subdir = mash/rstl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +librstl_la_LIBADD = +am_librstl_la_OBJECTS = rstl.lo +librstl_la_OBJECTS = $(am_librstl_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_$(V)) +am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(librstl_la_SOURCES) +DIST_SOURCES = $(librstl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/elias/workspace/mash/missing aclocal-1.15 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 0 +AR = ar +AUTOCONF = ${SHELL} /home/elias/workspace/mash/missing autoconf +AUTOHEADER = ${SHELL} /home/elias/workspace/mash/missing autoheader +AUTOMAKE = ${SHELL} /home/elias/workspace/mash/missing automake-1.15 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CLUTTER_CFLAGS = -pthread -I/usr/local/include/cogl -I/usr/include/clutter-1.0 -I/usr/include/atk-1.0 -I/usr/include/libdrm -I/usr/include/json-glib-1.0 -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include +CLUTTER_LIBS = -L/usr/local/lib -lclutter-1.0 -lcogl-path -latk-1.0 -lcogl-pango -lcogl -lgmodule-2.0 -pthread -lwayland-egl -lgbm -ldrm -lEGL -lXrandr -ljson-glib-1.0 -lgio-2.0 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgobject-2.0 -lglib-2.0 -lwayland-cursor -lwayland-client -lxkbcommon -lwayland-server -lX11 -lXext -lXdamage -lXfixes -lXcomposite -lXi +CLUTTER_PREFIX = /usr +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = false +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +FGREP = /bin/grep -F +GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include +GLIB_LIBS = -lgobject-2.0 -lglib-2.0 +GLIB_MKENUMS = /usr/bin/glib-mkenums +GREP = /bin/grep +GTKDOC_CHECK = gtkdoc-check.test +GTKDOC_CHECK_PATH = /usr/bin/gtkdoc-check +GTKDOC_DEPS_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include +GTKDOC_DEPS_LIBS = -lgobject-2.0 -lglib-2.0 +GTKDOC_MKPDF = /usr/bin/gtkdoc-mkpdf +GTKDOC_REBASE = /usr/bin/gtkdoc-rebase +HTML_DIR = ${datadir}/gtk-doc/html +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +INTROSPECTION_COMPILER = /usr/bin/g-ir-compiler +INTROSPECTION_GENERATE = /usr/bin/g-ir-generate +INTROSPECTION_GIRDIR = /usr/share/gir-1.0 +INTROSPECTION_SCANNER = /usr/bin/g-ir-scanner +INTROSPECTION_TYPELIBDIR = /usr/lib/x86_64-linux-gnu/girepository-1.0 +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = +LIBOBJS = +LIBS = -lm +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +LT_SYS_LIBRARY_PATH = +MAKEINFO = ${SHELL} /home/elias/workspace/mash/missing makeinfo +MANIFEST_TOOL = : +MASH_API_VERSION = 0.3 +MASH_LT_AGE = 0 +MASH_LT_CURRENT = 0 +MASH_LT_REVISION = 0 +MASH_MAJOR_VERSION = 0 +MASH_MICRO_VERSION = 1 +MASH_MINOR_VERSION = 3 +MASH_VERSION = 0.3.1 +MKDIR_P = /bin/mkdir -p +MX_CFLAGS = +MX_LIBS = +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = mash +PACKAGE_BUGREPORT = +PACKAGE_NAME = mash +PACKAGE_STRING = mash 0.3.1 +PACKAGE_TARNAME = mash +PACKAGE_URL = +PACKAGE_VERSION = 0.3.1 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/bash +STRIP = strip +VERSION = 0.3.1 +abs_builddir = /home/elias/workspace/mash/mash/rstl +abs_srcdir = /home/elias/workspace/mash/mash/rstl +abs_top_builddir = /home/elias/workspace/mash +abs_top_srcdir = /home/elias/workspace/mash +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = ${exec_prefix}/bin +build = x86_64-pc-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = x86_64-pc-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/elias/workspace/mash/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = $(MKDIR_P) +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +runstatedir = ${localstatedir}/run +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../../ +top_builddir = ../.. +top_srcdir = ../.. +noinst_LTLIBRARIES = librstl.la +AM_CPPFLAGS = \ + -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include + +librstl_la_SOURCES = \ + rstl.c \ + rstl.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mash/rstl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu mash/rstl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +librstl.la: $(librstl_la_OBJECTS) $(librstl_la_DEPENDENCIES) $(EXTRA_librstl_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(librstl_la_OBJECTS) $(librstl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/rstl.Plo + +.c.o: + $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# $(AM_V_CC)source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +# $(AM_V_CC)source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/mash/rstl/Makefile.am b/mash/rstl/Makefile.am new file mode 100644 index 0000000..8395b8d --- /dev/null +++ b/mash/rstl/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = librstl.la + +AM_CPPFLAGS = \ + @GLIB_CFLAGS@ + +librstl_la_SOURCES = \ + rstl.c \ + rstl.h diff --git a/mash/rstl/Makefile.am~ b/mash/rstl/Makefile.am~ new file mode 100644 index 0000000..8395b8d --- /dev/null +++ b/mash/rstl/Makefile.am~ @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = librstl.la + +AM_CPPFLAGS = \ + @GLIB_CFLAGS@ + +librstl_la_SOURCES = \ + rstl.c \ + rstl.h diff --git a/mash/rstl/Makefile.in b/mash/rstl/Makefile.in new file mode 100644 index 0000000..da5ad7f --- /dev/null +++ b/mash/rstl/Makefile.in @@ -0,0 +1,621 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = mash/rstl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +librstl_la_LIBADD = +am_librstl_la_OBJECTS = rstl.lo +librstl_la_OBJECTS = $(am_librstl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(librstl_la_SOURCES) +DIST_SOURCES = $(librstl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLUTTER_CFLAGS = @CLUTTER_CFLAGS@ +CLUTTER_LIBS = @CLUTTER_LIBS@ +CLUTTER_PREFIX = @CLUTTER_PREFIX@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MASH_API_VERSION = @MASH_API_VERSION@ +MASH_LT_AGE = @MASH_LT_AGE@ +MASH_LT_CURRENT = @MASH_LT_CURRENT@ +MASH_LT_REVISION = @MASH_LT_REVISION@ +MASH_MAJOR_VERSION = @MASH_MAJOR_VERSION@ +MASH_MICRO_VERSION = @MASH_MICRO_VERSION@ +MASH_MINOR_VERSION = @MASH_MINOR_VERSION@ +MASH_VERSION = @MASH_VERSION@ +MKDIR_P = @MKDIR_P@ +MX_CFLAGS = @MX_CFLAGS@ +MX_LIBS = @MX_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LTLIBRARIES = librstl.la +AM_CPPFLAGS = \ + @GLIB_CFLAGS@ + +librstl_la_SOURCES = \ + rstl.c \ + rstl.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mash/rstl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu mash/rstl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +librstl.la: $(librstl_la_OBJECTS) $(librstl_la_DEPENDENCIES) $(EXTRA_librstl_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(librstl_la_OBJECTS) $(librstl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rstl.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/mash/rstl/rstl.c b/mash/rstl/rstl.c new file mode 100644 index 0000000..def86e9 --- /dev/null +++ b/mash/rstl/rstl.c @@ -0,0 +1,1673 @@ +/* ---------------------------------------------------------------------- + * RStl library, read/write STL files + * Diego Nehab, Princeton University + * http://www.cs.princeton.edu/~diego/professional/rstl + * + * This library is distributed under the MIT License. See notice + * at the end of this file. + * ---------------------------------------------------------------------- */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rstl.h" + +/* ---------------------------------------------------------------------- + * Constants + * ---------------------------------------------------------------------- */ +#define WORDSIZE 256 +#define LINESIZE 1024 +#define BUFFERSIZE (8*1024) + +typedef enum e_stl_io_mode_ { + STL_READ, + STL_WRITE +} e_stl_io_mode; + +static const char *const stl_storage_mode_list[] = { + "binary_big_endian", "binary_little_endian", "ascii", NULL +}; /* order matches e_stl_storage_mode enum */ + +static const char *const stl_type_list[] = { + "int8", "uint8", "int16", "uint16", + "int32", "uint32", "float32", "float64", + "char", "uchar", "short", "ushort", + "int", "uint", "float", "double", + "list", NULL +}; /* order matches e_stl_type enum */ + +/* ---------------------------------------------------------------------- + * Property reading callback argument + * + * element: name of element being processed + * property: name of property being processed + * nelements: number of elements of this kind in file + * instance_index: index current element of this kind being processed + * length: number of values in current list (or 1 for scalars) + * value_index: index of current value int this list (or 0 for scalars) + * value: value of property + * pdata/idata: user data defined with stl_set_cb + * + * Returns handle to stl file if succesful, NULL otherwise. + * ---------------------------------------------------------------------- */ +typedef struct t_stl_argument_ { + p_stl_element element; + gint32 instance_index; + p_stl_property property; + gint32 length, value_index; + double value; + void *pdata; + long idata; +} t_stl_argument; + +/* ---------------------------------------------------------------------- + * Property information + * + * name: name of this property + * type: type of this property (list or type of scalar value) + * length_type, value_type: type of list property count and values + * read_cb: function to be called when this property is called + * + * Returns 1 if should continue processing file, 0 if should abort. + * ---------------------------------------------------------------------- */ +typedef struct t_stl_property_ { + char name[WORDSIZE]; + e_stl_type type, value_type, length_type; + p_stl_read_cb read_cb; + void *pdata; + long idata; +} t_stl_property; + +/* ---------------------------------------------------------------------- + * Element information + * + * name: name of this property + * ninstances: number of elements of this type in file + * property: property descriptions for this element + * nproperty: number of properties in this element + * + * Returns 1 if should continue processing file, 0 if should abort. + * ---------------------------------------------------------------------- */ +typedef struct t_stl_element_ { + char name[WORDSIZE]; + gint32 ninstances; + p_stl_property property; + gint32 nproperties; +} t_stl_element; + +/* ---------------------------------------------------------------------- + * Input/output driver + * + * Depending on file mode, different functions are used to read/write + * property fields. The drivers make it transparent to read/write in ascii, + * big endian or little endian cases. + * ---------------------------------------------------------------------- */ +typedef int (*p_stl_ihandler)(p_stl stl, double *value); +typedef int (*p_stl_ichunk)(p_stl stl, void *anydata, size_t size); +typedef struct t_stl_idriver_ { + p_stl_ihandler ihandler[18]; + p_stl_ichunk ichunk; + const char *name; +} t_stl_idriver; +typedef t_stl_idriver *p_stl_idriver; + +typedef int (*p_stl_ohandler)(p_stl stl, double value); +typedef int (*p_stl_ochunk)(p_stl stl, void *anydata, size_t size); +typedef struct t_stl_odriver_ { + p_stl_ohandler ohandler[16]; + p_stl_ochunk ochunk; + const char *name; +} t_stl_odriver; +typedef t_stl_odriver *p_stl_odriver; + +/* ---------------------------------------------------------------------- + * Stl file handle. + * + * io_mode: read or write (from e_stl_io_mode) + * storage_mode: mode of file associated with handle (from e_stl_storage_mode) + * element: elements description for this file + * nelement: number of different elements in file + * comment: comments for this file + * ncomments: number of comments in file + * obj_info: obj_info items for this file + * nobj_infos: number of obj_info items in file + * fp: file pointer associated with stl file + * c: last character read from stl file + * buffer: last word/chunck of data read from stl file + * buffer_first, buffer_last: interval of untouched good data in buffer + * buffer_token: start of parsed token (line or word) in buffer + * idriver, odriver: input driver used to get property fields from file + * argument: storage space for callback arguments + * welement, wproperty: element/property type being written + * winstance_index: index of instance of current element being written + * wvalue_index: index of list property value being written + * wlength: number of values in list property being written + * error_cb: callback for error messages + * ---------------------------------------------------------------------- */ +typedef struct t_stl_ { + e_stl_io_mode io_mode; + e_stl_storage_mode storage_mode; + p_stl_element element; + gint32 nelements; + char *comment; + gint32 ncomments; + char *obj_info; + gint32 nobj_infos; + FILE *fp; + int c; + char buffer[BUFFERSIZE]; + size_t buffer_first, buffer_token, buffer_last; + p_stl_idriver idriver; + p_stl_odriver odriver; + t_stl_argument argument; + gint32 welement, wproperty; + gint32 winstance_index, wvalue_index, wlength; + p_stl_error_cb error_cb; + gpointer cb_data; + int is_binary; +} t_stl; + +/* ---------------------------------------------------------------------- + * I/O functions and drivers + * ---------------------------------------------------------------------- */ +static t_stl_idriver stl_idriver_ascii; +static t_stl_idriver stl_idriver_binary; +static t_stl_idriver stl_idriver_binary_reverse; +static t_stl_odriver stl_odriver_ascii; +static t_stl_odriver stl_odriver_binary; +static t_stl_odriver stl_odriver_binary_reverse; + +static int stl_read_word(p_stl stl); +static int stl_check_word(p_stl stl); +static int stl_read_line(p_stl stl); +static int stl_check_line(p_stl stl); +static int stl_read_chunk(p_stl stl, void *anybuffer, size_t size); +static int stl_read_chunk_reverse(p_stl stl, void *anybuffer, size_t size); +static int stl_write_chunk(p_stl stl, void *anybuffer, size_t size); +static int stl_write_chunk_reverse(p_stl stl, void *anybuffer, size_t size); +static void stl_reverse(void *anydata, size_t size); + +/* ---------------------------------------------------------------------- + * String functions + * ---------------------------------------------------------------------- */ +static int stl_find_string(const char *item, const char* const list[]); +static p_stl_element stl_find_element(p_stl stl, const char *name); +static p_stl_property stl_find_property(p_stl_element element, + const char *name); + +/* ---------------------------------------------------------------------- + * Header parsing + * ---------------------------------------------------------------------- */ +static int stl_read_header_format(p_stl stl); +static int stl_read_header_comment(p_stl stl); +static int stl_read_header_obj_info(p_stl stl); +static int stl_read_header_property(p_stl stl); +static int stl_set_header_property(p_stl stl, char* name, int type); +static int stl_read_header_element(p_stl stl); +static int stl_set_header_element(p_stl stl, char* name, int val); + +/* ---------------------------------------------------------------------- + * Error handling + * ---------------------------------------------------------------------- */ +static void stl_error_cb(const char *message, gpointer data); +static void stl_error(p_stl stl, const char *fmt, ...); + +/* ---------------------------------------------------------------------- + * Memory allocation and initialization + * ---------------------------------------------------------------------- */ +static void stl_init(p_stl stl); +static void stl_element_init(p_stl_element element); +static void stl_property_init(p_stl_property property); +static p_stl stl_alloc(void); +static p_stl_element stl_grow_element(p_stl stl); +static p_stl_property stl_grow_property(p_stl stl, p_stl_element element); +static void *stl_grow_array(p_stl stl, void **pointer, gint32 *nmemb, gint32 size); + +/* ---------------------------------------------------------------------- + * Special functions + * ---------------------------------------------------------------------- */ +static e_stl_storage_mode stl_arch_endian(void); +static int stl_type_check(void); + +/* ---------------------------------------------------------------------- + * Auxiliary read functions + * ---------------------------------------------------------------------- */ +static int stl_read_element(p_stl stl, p_stl_element element, + p_stl_argument argument); +static int stl_read_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument); +static int stl_read_list_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument); +static int stl_read_scalar_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument); + + +/* ---------------------------------------------------------------------- + * Buffer support functions + * ---------------------------------------------------------------------- */ +/* pointers to tokenized word and line in buffer */ +#define BWORD(p) (p->buffer + p->buffer_token) +#define BLINE(p) (p->buffer + p->buffer_token) + +/* pointer to start of untouched bytes in buffer */ +#define BFIRST(p) (p->buffer + p->buffer_first) + +/* number of bytes untouched in buffer */ +#define BSIZE(p) (p->buffer_last - p->buffer_first) + +/* consumes data from buffer */ +#define BSKIP(p, s) (p->buffer_first += s) + +/* refills the buffer */ +static int BREFILL(p_stl stl) { + /* move untouched data to beginning of buffer */ + size_t size = BSIZE(stl); + memmove(stl->buffer, BFIRST(stl), size); + stl->buffer_last = size; + stl->buffer_first = stl->buffer_token = 0; + /* fill remaining with new data */ + size = fread(stl->buffer+size, 1, BUFFERSIZE-size-1, stl->fp); + /* place sentinel so we can use str* functions with buffer */ + stl->buffer[BUFFERSIZE-1] = '\0'; + /* check if read failed */ + if (size <= 0) return 0; + /* increase size to account for new data */ + stl->buffer_last += size; + return 1; +} + +/* ---------------------------------------------------------------------- + * Exported functions + * ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + * Read support functions + * ---------------------------------------------------------------------- */ +p_stl stl_open(const char *name, p_stl_error_cb error_cb, gpointer cb_data) { + char magic[81] = " "; + FILE *fp = NULL; + p_stl stl = NULL; + int is_binary = 0; + + //fprintf(stderr, "stl_open\n"); + if (error_cb == NULL) + error_cb = stl_error_cb; + if (!stl_type_check()) { + error_cb("Incompatible type system", cb_data); + return NULL; + } + assert(name); + fp = fopen(name, "rb"); + if (!fp) { + error_cb("Unable to open file", cb_data); + return NULL; + } + if (fread(magic, 1, 5, fp) < 5) { + error_cb("Error reading from file", cb_data); + fclose(fp); + return NULL; + } + if (strncmp(magic, "solid", 5) == 0) { + //fprintf(stderr, "File starts with 'solid'\n"); + // The starts with sold, need to make sure it ends with endsolid + static const long max_len = 55 + 1; + char buf[max_len + 1]; + // now read that many bytes from the end of the file + fseek(fp, -max_len, SEEK_END); + int len = fread(buf, 1, max_len, fp); + //fprintf(stderr, "Read %i bytes\n", len); + + buf[len] = '\0'; + + if (strstr(buf, "endsolid") != NULL) { + //fprintf(stderr, "File ends with 'endsolid'\n"); + is_binary = 0; + fseek(fp, 5, SEEK_SET); + } + else{ + //fprintf(stderr, "No 'endsolid', it is a binary\n"); + is_binary = 1; + fseek(fp, 80, SEEK_SET); + } + } + else if(strcmp(magic, "COLOR") == 0){ + //fprintf(stderr, "Binary STL with COLOR:\n"); + is_binary = 1; + if (fread(magic, 1, 75, fp) < 75) { + error_cb("Error reading 80 char header from file", cb_data); + fclose(fp); + return NULL; + } + } + else{ + //fprintf(stderr, "Binary STL with no color %s \n", magic); + // Try reading 75 more chacters and then an integer + if (fread(magic, 1, 75, fp) < 75) { + error_cb("Error reading 80 char header from file", cb_data); + fclose(fp); + return NULL; + } + is_binary = 1; + } + + stl = stl_alloc(); + if (!stl) { + error_cb("Out of memory", cb_data); + fclose(fp); + return NULL; + } + stl->fp = fp; + stl->io_mode = STL_READ; + stl->error_cb = error_cb; + stl->cb_data = cb_data; + stl->is_binary = is_binary; + return stl; +} + +int stl_read_header(p_stl stl) { + int i; + guint32 nr_facets = 0; + assert(stl && stl->fp && stl->io_mode == STL_READ); + if(stl->is_binary){ + if( fread( &nr_facets, 1, 4, stl->fp ) < 4){ + fprintf(stderr, "Error reading number of facets\n"); + return 0; + } + else{ + //fprintf(stderr, "Read %i facets\n", nr_facets); + } + + // Set input driver + if (!stl_read_header_format(stl)) + return 0; + + stl_set_header_element(stl, "facet", nr_facets); + stl_set_header_property(stl, "nx", STL_FLOAT); + stl_set_header_property(stl, "ny", STL_FLOAT); + stl_set_header_property(stl, "nz", STL_FLOAT); + stl_set_header_property(stl, "x0", STL_FLOAT); + stl_set_header_property(stl, "y0", STL_FLOAT); + stl_set_header_property(stl, "z0", STL_FLOAT); + stl_set_header_property(stl, "x1", STL_FLOAT); + stl_set_header_property(stl, "y1", STL_FLOAT); + stl_set_header_property(stl, "z1", STL_FLOAT); + stl_set_header_property(stl, "x2", STL_FLOAT); + stl_set_header_property(stl, "y2", STL_FLOAT); + stl_set_header_property(stl, "z2", STL_FLOAT); + stl_set_header_property(stl, "attr", STL_UINT16); + } + else{ + // STL files do not have the number of vertices + // and normals, so we fake it. + while(1){ + if(!stl_read_word(stl)) + return 0; + if(strcmp(BWORD(stl), "facet") == 0) + nr_facets++; + else if(strcmp(BWORD(stl), "endsolid") == 0) + break; + } + // reinit to reset buffer pointers. + stl_init(stl); + rewind (stl->fp); + + if (!stl_read_header_format(stl)) return 0; + if (!stl_read_line(stl)) return 0; + + stl_set_header_element(stl, "facet", nr_facets); + stl_set_header_property(stl, "facet", STL_WORD); + stl_set_header_property(stl, "normal", STL_WORD); + stl_set_header_property(stl, "nx", STL_FLOAT); + stl_set_header_property(stl, "ny", STL_FLOAT); + stl_set_header_property(stl, "nz", STL_FLOAT); + stl_set_header_property(stl, "outer loop", STL_LINE); + stl_set_header_property(stl, "vertex", STL_WORD); + stl_set_header_property(stl, "x0", STL_FLOAT); + stl_set_header_property(stl, "y0", STL_FLOAT); + stl_set_header_property(stl, "z0", STL_FLOAT); + stl_set_header_property(stl, "vertex", STL_WORD); + stl_set_header_property(stl, "x1", STL_FLOAT); + stl_set_header_property(stl, "y1", STL_FLOAT); + stl_set_header_property(stl, "z1", STL_FLOAT); + stl_set_header_property(stl, "vertex", STL_WORD); + stl_set_header_property(stl, "x2", STL_FLOAT); + stl_set_header_property(stl, "y2", STL_FLOAT); + stl_set_header_property(stl, "z2", STL_FLOAT); + stl_set_header_property(stl, "endloop", STL_LINE); + stl_set_header_property(stl, "endfacet", STL_LINE); + } + return 1; +} + +long stl_set_read_cb(p_stl stl, const char *element_name, + const char* property_name, p_stl_read_cb read_cb, + void *pdata, long idata) { + //fprintf(stderr, "stl_set_read_cb '%s', '%s'\n", element_name, property_name); + + p_stl_element element = NULL; + p_stl_property property = NULL; + assert(stl && element_name && property_name); + + element = stl_find_element(stl, element_name); + if (!element) return 0; + property = stl_find_property(element, property_name); + if (!property) return 0; + //fprintf(stderr, "property was found\n"); + property->read_cb = read_cb; + property->pdata = pdata; + property->idata = idata; + return (int) element->ninstances; +} + + +int stl_read(p_stl stl) { + gint32 i; + p_stl_argument argument; + assert(stl && stl->fp && stl->io_mode == STL_READ); + argument = &stl->argument; + for (i = 0; i < stl->nelements; i++) { + //fprintf(stderr, "stl_read %i\n", i); + p_stl_element element = &stl->element[i]; + argument->element = element; + //fprintf(stderr, "stl_read reading element\n"); + if (!stl_read_element(stl, element, argument)) + return 0; + } + return 1; +} + +/* ---------------------------------------------------------------------- + * Write support functions + * ---------------------------------------------------------------------- */ +p_stl stl_create(const char *name, e_stl_storage_mode storage_mode, + p_stl_error_cb error_cb, gpointer cb_data) { + FILE *fp = NULL; + p_stl stl = NULL; + if (error_cb == NULL) error_cb = stl_error_cb; + if (!stl_type_check()) { + error_cb("Incompatible type system", cb_data); + return NULL; + } + assert(name && storage_mode <= STL_DEFAULT); + fp = fopen(name, "wb"); + if (!fp) { + error_cb("Unable to create file", cb_data); + return NULL; + } + stl = stl_alloc(); + if (!stl) { + fclose(fp); + error_cb("Out of memory", cb_data); + return NULL; + } + stl->io_mode = STL_WRITE; + if (storage_mode == STL_DEFAULT) storage_mode = stl_arch_endian(); + if (storage_mode == STL_ASCII) stl->odriver = &stl_odriver_ascii; + else if (storage_mode == stl_arch_endian()) + stl->odriver = &stl_odriver_binary; + else stl->odriver = &stl_odriver_binary_reverse; + stl->storage_mode = storage_mode; + stl->fp = fp; + stl->error_cb = error_cb; + stl->cb_data = cb_data; + return stl; +} + +int stl_add_element(p_stl stl, const char *name, gint32 ninstances) { + p_stl_element element = NULL; + assert(stl && stl->fp && stl->io_mode == STL_WRITE); + assert(name && strlen(name) < WORDSIZE && ninstances >= 0); + if (strlen(name) >= WORDSIZE || ninstances < 0) { + stl_error(stl, "Invalid arguments"); + return 0; + } + element = stl_grow_element(stl); + if (!element) return 0; + strcpy(element->name, name); + element->ninstances = ninstances; + return 1; +} + +int stl_add_scalar_property(p_stl stl, const char *name, e_stl_type type) { + p_stl_element element = NULL; + p_stl_property property = NULL; + assert(stl && stl->fp && stl->io_mode == STL_WRITE); + assert(name && strlen(name) < WORDSIZE); + assert(type < STL_LIST); + if (strlen(name) >= WORDSIZE || type >= STL_LIST) { + stl_error(stl, "Invalid arguments"); + return 0; + } + element = &stl->element[stl->nelements-1]; + property = stl_grow_property(stl, element); + if (!property) return 0; + strcpy(property->name, name); + property->type = type; + return 1; +} + +int stl_add_list_property(p_stl stl, const char *name, + e_stl_type length_type, e_stl_type value_type) { + p_stl_element element = NULL; + p_stl_property property = NULL; + assert(stl && stl->fp && stl->io_mode == STL_WRITE); + assert(name && strlen(name) < WORDSIZE); + if (strlen(name) >= WORDSIZE) { + stl_error(stl, "Invalid arguments"); + return 0; + } + assert(length_type < STL_LIST); + assert(value_type < STL_LIST); + if (length_type >= STL_LIST || value_type >= STL_LIST) { + stl_error(stl, "Invalid arguments"); + return 0; + } + element = &stl->element[stl->nelements-1]; + property = stl_grow_property(stl, element); + if (!property) return 0; + strcpy(property->name, name); + property->type = STL_LIST; + property->length_type = length_type; + property->value_type = value_type; + return 1; +} + +int stl_add_property(p_stl stl, const char *name, e_stl_type type, + e_stl_type length_type, e_stl_type value_type) { + if (type == STL_LIST) + return stl_add_list_property(stl, name, length_type, value_type); + else + return stl_add_scalar_property(stl, name, type); +} + +int stl_add_comment(p_stl stl, const char *comment) { + char *new_comment = NULL; + assert(stl && comment && strlen(comment) < LINESIZE); + if (!comment || strlen(comment) >= LINESIZE) { + stl_error(stl, "Invalid arguments"); + return 0; + } + new_comment = (char *) stl_grow_array(stl, (void **) &stl->comment, + &stl->ncomments, LINESIZE); + if (!new_comment) return 0; + strcpy(new_comment, comment); + return 1; +} + +int stl_add_obj_info(p_stl stl, const char *obj_info) { + char *new_obj_info = NULL; + assert(stl && obj_info && strlen(obj_info) < LINESIZE); + if (!obj_info || strlen(obj_info) >= LINESIZE) { + stl_error(stl, "Invalid arguments"); + return 0; + } + new_obj_info = (char *) stl_grow_array(stl, (void **) &stl->obj_info, + &stl->nobj_infos, LINESIZE); + if (!new_obj_info) return 0; + strcpy(new_obj_info, obj_info); + return 1; +} + +int stl_write_header(p_stl stl) { + gint32 i, j; + assert(stl && stl->fp && stl->io_mode == STL_WRITE); + assert(stl->element || stl->nelements == 0); + assert(!stl->element || stl->nelements > 0); + if (fprintf(stl->fp, "stl\nformat %s 1.0\n", + stl_storage_mode_list[stl->storage_mode]) <= 0) goto error; + for (i = 0; i < stl->ncomments; i++) + if (fprintf(stl->fp, "comment %s\n", stl->comment + LINESIZE*i) <= 0) + goto error; + for (i = 0; i < stl->nobj_infos; i++) + if (fprintf(stl->fp, "obj_info %s\n", stl->obj_info + LINESIZE*i) <= 0) + goto error; + for (i = 0; i < stl->nelements; i++) { + p_stl_element element = &stl->element[i]; + assert(element->property || element->nproperties == 0); + assert(!element->property || element->nproperties > 0); + if (fprintf(stl->fp, "element %s %" G_GINT32_FORMAT " \n", element->name, + element->ninstances) <= 0) goto error; + for (j = 0; j < element->nproperties; j++) { + p_stl_property property = &element->property[j]; + if (property->type == STL_LIST) { + if (fprintf(stl->fp, "property list %s %s %s\n", + stl_type_list[property->length_type], + stl_type_list[property->value_type], + property->name) <= 0) goto error; + } else { + if (fprintf(stl->fp, "property %s %s\n", + stl_type_list[property->type], + property->name) <= 0) goto error; + } + } + } + return fprintf(stl->fp, "end_header\n") > 0; +error: + stl_error(stl, "Error writing to file"); + return 0; +} + +int stl_write(p_stl stl, double value) { + p_stl_element element = NULL; + p_stl_property property = NULL; + int type = -1; + int breakafter = 0; + if (stl->welement > stl->nelements) return 0; + element = &stl->element[stl->welement]; + if (stl->wproperty > element->nproperties) return 0; + property = &element->property[stl->wproperty]; + if (property->type == STL_LIST) { + if (stl->wvalue_index == 0) { + type = property->length_type; + stl->wlength = (gint32) value; + } else type = property->value_type; + } else { + type = property->type; + stl->wlength = 0; + } + if (!stl->odriver->ohandler[type](stl, value)) { + stl_error(stl, "Failed writing %s of %s %d (%s: %s)", + property->name, element->name, + stl->winstance_index, + stl->odriver->name, stl_type_list[type]); + return 0; + } + stl->wvalue_index++; + if (stl->wvalue_index > stl->wlength) { + stl->wvalue_index = 0; + stl->wproperty++; + } + if (stl->wproperty >= element->nproperties) { + stl->wproperty = 0; + stl->winstance_index++; + if (stl->storage_mode == STL_ASCII) breakafter = 1; + } + if (stl->winstance_index >= element->ninstances) { + stl->winstance_index = 0; + stl->welement++; + } + return !breakafter || putc('\n', stl->fp) > 0; +} + +int stl_close(p_stl stl) { + gint32 i; + assert(stl && stl->fp); + assert(stl->element || stl->nelements == 0); + assert(!stl->element || stl->nelements > 0); + /* write last chunk to file */ + if (stl->io_mode == STL_WRITE && + fwrite(stl->buffer, 1, stl->buffer_last, stl->fp) < stl->buffer_last) { + stl_error(stl, "Error closing up"); + return 0; + } + fclose(stl->fp); + /* free all memory used by handle */ + if (stl->element) { + for (i = 0; i < stl->nelements; i++) { + p_stl_element element = &stl->element[i]; + if (element->property) free(element->property); + } + free(stl->element); + } + if (stl->obj_info) free(stl->obj_info); + if (stl->comment) free(stl->comment); + free(stl); + return 1; +} + +/* ---------------------------------------------------------------------- + * Query support functions + * ---------------------------------------------------------------------- */ +p_stl_element stl_get_next_element(p_stl stl, + p_stl_element last) { + assert(stl); + if (!last) return stl->element; + last++; + if (last < stl->element + stl->nelements) return last; + else return NULL; +} + +int stl_get_element_info(p_stl_element element, const char** name, + gint32 *ninstances) { + assert(element); + if (name) *name = element->name; + if (ninstances) + *ninstances = (gint32) 12*4; // 12 floating points + return 1; +} + +p_stl_property stl_get_next_property(p_stl_element element, + p_stl_property last) { + assert(element); + if (!last) return element->property; + last++; + if (last < element->property + element->nproperties) return last; + else return NULL; +} + +int stl_get_property_info(p_stl_property property, const char** name, + e_stl_type *type, e_stl_type *length_type, e_stl_type *value_type) { + assert(property); + if (name) *name = property->name; + if (type) *type = property->type; + if (length_type) *length_type = property->length_type; + if (value_type) *value_type = property->value_type; + return 1; + +} + +const char *stl_get_next_comment(p_stl stl, const char *last) { + assert(stl); + if (!last) return stl->comment; + last += LINESIZE; + if (last < stl->comment + LINESIZE*stl->ncomments) return last; + else return NULL; +} + +const char *stl_get_next_obj_info(p_stl stl, const char *last) { + assert(stl); + if (!last) return stl->obj_info; + last += LINESIZE; + if (last < stl->obj_info + LINESIZE*stl->nobj_infos) return last; + else return NULL; +} + +/* ---------------------------------------------------------------------- + * Callback argument support functions + * ---------------------------------------------------------------------- */ +int stl_get_argument_element(p_stl_argument argument, + p_stl_element *element, gint32 *instance_index) { + assert(argument); + if (!argument) return 0; + if (element) *element = argument->element; + if (instance_index) *instance_index = argument->instance_index; + return 1; +} + +int stl_get_argument_property(p_stl_argument argument, + p_stl_property *property, gint32 *length, gint32 *value_index) { + assert(argument); + if (!argument) return 0; + if (property) *property = argument->property; + if (length) *length = argument->length; + if (value_index) *value_index = argument->value_index; + return 1; +} + +int stl_get_argument_user_data(p_stl_argument argument, void **pdata, + long *idata) { + assert(argument); + if (!argument) return 0; + if (pdata) *pdata = argument->pdata; + if (idata) *idata = argument->idata; + return 1; +} + +double stl_get_argument_value(p_stl_argument argument) { + assert(argument); + if (!argument) return 0.0; + return argument->value; +} + +/* ---------------------------------------------------------------------- + * Internal functions + * ---------------------------------------------------------------------- */ +static int stl_read_list_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument) { + int l; + p_stl_read_cb read_cb = property->read_cb; + p_stl_ihandler *driver = stl->idriver->ihandler; + /* get list length */ + p_stl_ihandler handler = driver[property->length_type]; + double length; + if (!handler(stl, &length)) { + stl_error(stl, "Error reading '%s' of '%s' number %d", + property->name, element->name, argument->instance_index); + return 0; + } + /* invoke callback to pass length in value field */ + argument->length = (gint32) length; + argument->value_index = -1; + argument->value = length; + if (read_cb && !read_cb(argument)) { + stl_error(stl, "Aborted by user"); + return 0; + } + /* read list values */ + handler = driver[property->value_type]; + /* for each value in list */ + for (l = 0; l < (gint32) length; l++) { + /* read value from file */ + argument->value_index = l; + if (!handler(stl, &argument->value)) { + stl_error(stl, "Error reading value number %d of '%s' of " + "'%s' number %d", l+1, property->name, + element->name, argument->instance_index); + return 0; + } + /* invoke callback to pass value */ + if (read_cb && !read_cb(argument)) { + stl_error(stl, "Aborted by user"); + return 0; + } + } + return 1; +} + +static int stl_read_scalar_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument) { + //fprintf(stderr, "stl_read_scalar_property\n"); + p_stl_read_cb read_cb = property->read_cb; + p_stl_ihandler *driver = stl->idriver->ihandler; + p_stl_ihandler handler = driver[property->type]; + argument->length = 1; + argument->value_index = 0; + if (!handler(stl, &argument->value)) { + stl_error(stl, "Error reading '%s' of '%s' number %d", + property->name, element->name, argument->instance_index); + return 0; + } + if (read_cb && !read_cb(argument)) { + stl_error(stl, "Aborted by user"); + return 0; + } + return 1; +} + +static int stl_read_property(p_stl stl, p_stl_element element, + p_stl_property property, p_stl_argument argument) { + if (property->type == STL_LIST) + return stl_read_list_property(stl, element, property, argument); + else + return stl_read_scalar_property(stl, element, property, argument); +} + +static int stl_read_element(p_stl stl, p_stl_element element, + p_stl_argument argument) { + gint32 j, k; + /* for each element of this type */ + for (j = 0; j < element->ninstances; j++) { + //fprintf(stderr, "reading element %d of %d\n", j, element->ninstances); + argument->instance_index = j; + /* for each property */ + for (k = 0; k < element->nproperties; k++) { + //fprintf(stderr, "reading property %d of %d\n", k, element->nproperties); + p_stl_property property = &element->property[k]; + argument->property = property; + argument->pdata = property->pdata; + argument->idata = property->idata; + if (!stl_read_property(stl, element, property, argument)) + return 0; + } + } + return 1; +} + +static int stl_find_string(const char *item, const char* const list[]) { + int i; + assert(item && list); + for (i = 0; list[i]; i++) + if (!strcmp(list[i], item)) return i; + return -1; +} + +static p_stl_element stl_find_element(p_stl stl, const char *name) { + p_stl_element element; + int i, nelements; + + assert(stl && name); + element = stl->element; + nelements = stl->nelements; + assert(element || nelements == 0); + assert(!element || nelements > 0); + for (i = 0; i < nelements; i++) + if (!strcmp(element[i].name, name)) return &element[i]; + return NULL; +} + +static p_stl_property stl_find_property(p_stl_element element, + const char *name) { + p_stl_property property; + int i, nproperties; + assert(element && name); + property = element->property; + nproperties = element->nproperties; + assert(property || nproperties == 0); + assert(!property || nproperties > 0); + for (i = 0; i < nproperties; i++) + if (!strcmp(property[i].name, name)) return &property[i]; + return NULL; +} + +static int stl_check_word(p_stl stl) { + if (strlen(BLINE(stl)) >= WORDSIZE) { + stl_error(stl, "Word too gint32"); + return 0; + } + return 1; +} + +static int stl_read_word(p_stl stl) { + size_t t = 0; + assert(stl && stl->fp && stl->io_mode == STL_READ); + /* skip leading blanks */ + while (1) { + t = strspn(BFIRST(stl), " \n\r\t"); + /* check if all buffer was made of blanks */ + if (t >= BSIZE(stl)) { + if (!BREFILL(stl)) { + stl_error(stl, "Unexpected end of file"); + return 0; + } + } else break; + } + BSKIP(stl, t); + /* look for a space after the current word */ + t = strcspn(BFIRST(stl), " \n\r\t"); + /* if we didn't reach the end of the buffer, we are done */ + if (t < BSIZE(stl)) { + stl->buffer_token = stl->buffer_first; + BSKIP(stl, t); + *BFIRST(stl) = '\0'; + BSKIP(stl, 1); + return stl_check_word(stl); + } + /* otherwise, try to refill buffer */ + if (!BREFILL(stl)) { + stl_error(stl, "Unexpected end of file"); + return 0; + } + /* keep looking from where we left */ + t += strcspn(BFIRST(stl) + t, " \n\r\t"); + /* check if the token is too large for our buffer */ + if (t >= BSIZE(stl)) { + stl_error(stl, "Token too large"); + return 0; + } + /* we are done */ + stl->buffer_token = stl->buffer_first; + BSKIP(stl, t); + *BFIRST(stl) = '\0'; + BSKIP(stl, 1); + return stl_check_word(stl); +} + +static int stl_check_line(p_stl stl) { + if (strlen(BLINE(stl)) >= LINESIZE) { + stl_error(stl, "Line too gint32"); + return 0; + } + return 1; +} + +static int stl_read_line(p_stl stl) { + const char *end = NULL; + assert(stl && stl->fp && stl->io_mode == STL_READ); + /* look for a end of line */ + end = strchr(BFIRST(stl), '\n'); + /* if we didn't reach the end of the buffer, we are done */ + if (end) { + stl->buffer_token = stl->buffer_first; + BSKIP(stl, end - BFIRST(stl)); + *BFIRST(stl) = '\0'; + BSKIP(stl, 1); + return stl_check_line(stl); + } else { + end = stl->buffer + BSIZE(stl); + /* otherwise, try to refill buffer */ + if (!BREFILL(stl)) { + stl_error(stl, "Unexpected end of file"); + return 0; + } + } + /* keep looking from where we left */ + end = strchr(end, '\n'); + /* check if the token is too large for our buffer */ + if (!end) { + stl_error(stl, "Token too large"); + return 0; + } + /* we are done */ + stl->buffer_token = stl->buffer_first; + BSKIP(stl, end - BFIRST(stl)); + *BFIRST(stl) = '\0'; + BSKIP(stl, 1); + return stl_check_line(stl); +} + +static int stl_read_chunk(p_stl stl, void *anybuffer, size_t size) { + char *buffer = (char *) anybuffer; + size_t i = 0; + assert(stl && stl->fp && stl->io_mode == STL_READ); + assert(stl->buffer_first <= stl->buffer_last); + while (i < size) { + if (stl->buffer_first < stl->buffer_last) { + buffer[i] = stl->buffer[stl->buffer_first]; + stl->buffer_first++; + i++; + } else { + stl->buffer_first = 0; + stl->buffer_last = fread(stl->buffer, 1, BUFFERSIZE, stl->fp); + if (stl->buffer_last <= 0) return 0; + } + } + return 1; +} + +static int stl_write_chunk(p_stl stl, void *anybuffer, size_t size) { + char *buffer = (char *) anybuffer; + size_t i = 0; + assert(stl && stl->fp && stl->io_mode == STL_WRITE); + assert(stl->buffer_last <= BUFFERSIZE); + while (i < size) { + if (stl->buffer_last < BUFFERSIZE) { + stl->buffer[stl->buffer_last] = buffer[i]; + stl->buffer_last++; + i++; + } else { + stl->buffer_last = 0; + if (fwrite(stl->buffer, 1, BUFFERSIZE, stl->fp) < BUFFERSIZE) + return 0; + } + } + return 1; +} + +static int stl_write_chunk_reverse(p_stl stl, void *anybuffer, size_t size) { + int ret = 0; + stl_reverse(anybuffer, size); + ret = stl_write_chunk(stl, anybuffer, size); + stl_reverse(anybuffer, size); + return ret; +} + +static int stl_read_chunk_reverse(p_stl stl, void *anybuffer, size_t size) { + if (!stl_read_chunk(stl, anybuffer, size)) return 0; + stl_reverse(anybuffer, size); + return 1; +} + +static void stl_reverse(void *anydata, size_t size) { + char *data = (char *) anydata; + char temp; + size_t i; + for (i = 0; i < size/2; i++) { + temp = data[i]; + data[i] = data[size-i-1]; + data[size-i-1] = temp; + } +} + +static void stl_init(p_stl stl) { + stl->c = ' '; + stl->element = NULL; + stl->nelements = 0; + stl->comment = NULL; + stl->ncomments = 0; + stl->obj_info = NULL; + stl->nobj_infos = 0; + stl->idriver = NULL; + stl->odriver = NULL; + stl->buffer[0] = '\0'; + stl->buffer_first = stl->buffer_last = stl->buffer_token = 0; + stl->welement = 0; + stl->wproperty = 0; + stl->winstance_index = 0; + stl->wlength = 0; + stl->wvalue_index = 0; +} + +static void stl_element_init(p_stl_element element) { + element->name[0] = '\0'; + element->ninstances = 0; + element->property = NULL; + element->nproperties = 0; +} + +static void stl_property_init(p_stl_property property) { + property->name[0] = '\0'; + property->type = -1; + property->length_type = -1; + property->value_type = -1; + property->read_cb = (p_stl_read_cb) NULL; + property->pdata = NULL; + property->idata = 0; +} + +static p_stl stl_alloc(void) { + p_stl stl = (p_stl) malloc(sizeof(t_stl)); + if (!stl) return NULL; + stl_init(stl); + return stl; +} + +static void *stl_grow_array(p_stl stl, void **pointer, + gint32 *nmemb, gint32 size) { + void *temp = *pointer; + gint32 count = *nmemb + 1; + if (!temp) temp = malloc(count*size); + else temp = realloc(temp, count*size); + if (!temp) { + stl_error(stl, "Out of memory"); + return NULL; + } + *pointer = temp; + *nmemb = count; + return (char *) temp + (count-1) * size; +} + +static p_stl_element stl_grow_element(p_stl stl) { + p_stl_element element = NULL; + assert(stl); + assert(stl->element || stl->nelements == 0); + assert(!stl->element || stl->nelements > 0); + element = (p_stl_element) stl_grow_array(stl, (void **) &stl->element, + &stl->nelements, sizeof(t_stl_element)); + if (!element) return NULL; + stl_element_init(element); + return element; +} + +static p_stl_property stl_grow_property(p_stl stl, p_stl_element element) { + p_stl_property property = NULL; + assert(stl); + assert(element); + assert(element->property || element->nproperties == 0); + assert(!element->property || element->nproperties > 0); + property = (p_stl_property) stl_grow_array(stl, + (void **) &element->property, + &element->nproperties, sizeof(t_stl_property)); + if (!property) return NULL; + stl_property_init(property); + return property; +} + +static int stl_read_header_format(p_stl stl) { + assert(stl && stl->fp && stl->io_mode == STL_READ); + if(stl->is_binary) + stl->idriver = &stl_idriver_binary; + else + stl->idriver = &stl_idriver_ascii; + return 1; +} + +static int stl_read_header_comment(p_stl stl) { + assert(stl && stl->fp && stl->io_mode == STL_READ); + if (strcmp(BWORD(stl), "comment")) return 0; + if (!stl_read_line(stl)) return 0; + if (!stl_add_comment(stl, BLINE(stl))) return 0; + if (!stl_read_word(stl)) return 0; + return 1; +} + +static int stl_read_header_obj_info(p_stl stl) { + assert(stl && stl->fp && stl->io_mode == STL_READ); + if (strcmp(BWORD(stl), "obj_info")) return 0; + if (!stl_read_line(stl)) return 0; + if (!stl_add_obj_info(stl, BLINE(stl))) return 0; + if (!stl_read_word(stl)) return 0; + return 1; +} + +static int stl_read_header_property(p_stl stl) { + p_stl_element element = NULL; + p_stl_property property = NULL; + /* make sure it is a property */ + if (strcmp(BWORD(stl), "property")) return 0; + element = &stl->element[stl->nelements-1]; + property = stl_grow_property(stl, element); + if (!property) return 0; + /* get property type */ + if (!stl_read_word(stl)) return 0; + property->type = stl_find_string(BWORD(stl), stl_type_list); + if (property->type == (e_stl_type) (-1)) return 0; + if (property->type == STL_LIST) { + /* if it's a list, we need the base types */ + if (!stl_read_word(stl)) return 0; + property->length_type = stl_find_string(BWORD(stl), stl_type_list); + if (property->length_type == (e_stl_type) (-1)) return 0; + if (!stl_read_word(stl)) return 0; + property->value_type = stl_find_string(BWORD(stl), stl_type_list); + if (property->value_type == (e_stl_type) (-1)) return 0; + } + /* get property name */ + if (!stl_read_word(stl)) return 0; + strcpy(property->name, BWORD(stl)); + if (!stl_read_word(stl)) return 0; + return 1; +} + +static int stl_set_header_property(p_stl stl, char* name, int type) { + p_stl_element element = NULL; + p_stl_property property = NULL; + /* make sure it is a property */ + element = &stl->element[stl->nelements-1]; + property = stl_grow_property(stl, element); + if (!property) return 0; + /* get property type */ + property->type = type; + if (property->type == (e_stl_type) (-1)) return 0; + if (property->type == STL_LIST) { + /* if it's a list, we need the base types */ + property->length_type = STL_UCHAR; + property->value_type = STL_INT; + } + /* get property name */ + strcpy(property->name, name); + return 1; +} + +static int stl_read_header_element(p_stl stl) { + p_stl_element element = NULL; + gint32 dummy; + assert(stl && stl->fp && stl->io_mode == STL_READ); + if (strcmp(BWORD(stl), "element")) return 0; + /* allocate room for new element */ + element = stl_grow_element(stl); + if (!element) return 0; + /* get element name */ + if (!stl_read_word(stl)) return 0; + strcpy(element->name, BWORD(stl)); + /* get number of elements of this type */ + if (!stl_read_word(stl)) return 0; + if (sscanf(BWORD(stl), "%" G_GINT32_FORMAT, &dummy) != 1) { + stl_error(stl, "Expected number got '%s'", BWORD(stl)); + return 0; + } + element->ninstances = dummy; + /* get all properties for this element */ + if (!stl_read_word(stl)) return 0; + while (stl_read_header_property(stl) || + stl_read_header_comment(stl) || stl_read_header_obj_info(stl)) + /* do nothing */; + return 1; +} + + +static int stl_set_header_element(p_stl stl, char* name, int val){ + p_stl_element element = NULL; + gint32 dummy; + assert(stl && stl->fp && stl->io_mode == STL_READ); + /* allocate room for new element */ + element = stl_grow_element(stl); + if (!element) return 0; + /* get element name */ + strcpy(element->name, name); + /* get number of elements of this type */ + element->ninstances = val; +} + +static void stl_error_cb(const char *message, gpointer data) { + fprintf(stderr, "RStl: %s\n", message); +} + +static void stl_error(p_stl stl, const char *fmt, ...) { + char buffer[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buffer, fmt, ap); + va_end(ap); + stl->error_cb(buffer, stl->cb_data); +} + +static e_stl_storage_mode stl_arch_endian(void) { + guint32 i = 1; + unsigned char *s = (unsigned char *) &i; + if (*s == 1) return STL_LITTLE_ENDIAN; + else return STL_BIG_ENDIAN; +} + +static int stl_type_check(void) { + assert(sizeof(char) == 1); + assert(sizeof(unsigned char) == 1); + assert(sizeof(gint16) == 2); + assert(sizeof(guint16) == 2); + assert(sizeof(gint32) == 4); + assert(sizeof(guint32) == 4); + assert(sizeof(float) == 4); + assert(sizeof(double) == 8); + if (sizeof(char) != 1) return 0; + if (sizeof(unsigned char) != 1) return 0; + if (sizeof(gint16) != 2) return 0; + if (sizeof(guint16) != 2) return 0; + if (sizeof(gint32) != 4) return 0; + if (sizeof(guint32) != 4) return 0; + if (sizeof(float) != 4) return 0; + if (sizeof(double) != 8) return 0; + return 1; +} + +/* ---------------------------------------------------------------------- + * Output handlers + * ---------------------------------------------------------------------- */ +static int oascii_int8(p_stl stl, double value) { + if (value > CHAR_MAX || value < CHAR_MIN) return 0; + return fprintf(stl->fp, "%d ", (char) value) > 0; +} + +static int oascii_uint8(p_stl stl, double value) { + if (value > UCHAR_MAX || value < 0) return 0; + return fprintf(stl->fp, "%d ", (unsigned char) value) > 0; +} + +static int oascii_int16(p_stl stl, double value) { + if (value > G_MAXINT16 || value < G_MININT16) return 0; + return fprintf(stl->fp, "%d ", (gint16) value) > 0; +} + +static int oascii_uint16(p_stl stl, double value) { + if (value > G_MAXUINT16 || value < 0) return 0; + return fprintf(stl->fp, "%d ", (guint16) value) > 0; +} + +static int oascii_int32(p_stl stl, double value) { + if (value > G_MAXINT32 || value < G_MININT32) return 0; + return fprintf(stl->fp, "%d ", (int) value) > 0; +} + +static int oascii_uint32(p_stl stl, double value) { + if (value > G_MAXUINT32 || value < 0) return 0; + return fprintf(stl->fp, "%d ", (unsigned int) value) > 0; +} + +static int oascii_float32(p_stl stl, double value) { + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + if (value < -FLT_MAX || value > FLT_MAX) return 0; + return fprintf(stl->fp, "%s ", + g_ascii_formatd(buf, sizeof (buf), "%g", (float) value)) > 0; +} + +static int oascii_float64(p_stl stl, double value) { + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + if (value < -DBL_MAX || value > DBL_MAX) return 0; + return fprintf(stl->fp, "%s ", + g_ascii_formatd(buf, sizeof (buf), "%g", value)) > 0; +} + +static int obinary_int8(p_stl stl, double value) { + char int8 = (char) value; + if (value > CHAR_MAX || value < CHAR_MIN) return 0; + return stl->odriver->ochunk(stl, &int8, sizeof(int8)); +} + +static int obinary_uint8(p_stl stl, double value) { + unsigned char uint8 = (unsigned char) value; + if (value > UCHAR_MAX || value < 0) return 0; + return stl->odriver->ochunk(stl, &uint8, sizeof(uint8)); +} + +static int obinary_int16(p_stl stl, double value) { + gint16 int16 = (gint16) value; + if (value > G_MAXINT16 || value < G_MININT16) return 0; + return stl->odriver->ochunk(stl, &int16, sizeof(int16)); +} + +static int obinary_uint16(p_stl stl, double value) { + guint16 uint16 = (guint16) value; + if (value > G_MAXUINT16 || value < 0) return 0; + return stl->odriver->ochunk(stl, &uint16, sizeof(uint16)); +} + +static int obinary_int32(p_stl stl, double value) { + gint32 int32 = (gint32) value; + if (value > G_MAXINT32 || value < G_MININT32) return 0; + return stl->odriver->ochunk(stl, &int32, sizeof(int32)); +} + +static int obinary_uint32(p_stl stl, double value) { + guint32 uint32 = (guint32) value; + if (value > G_MAXUINT32 || value < 0) return 0; + return stl->odriver->ochunk(stl, &uint32, sizeof(uint32)); +} + +static int obinary_float32(p_stl stl, double value) { + float float32 = (float) value; + if (value > FLT_MAX || value < -FLT_MAX) return 0; + return stl->odriver->ochunk(stl, &float32, sizeof(float32)); +} + +static int obinary_float64(p_stl stl, double value) { + return stl->odriver->ochunk(stl, &value, sizeof(value)); +} + +/* ---------------------------------------------------------------------- + * Input handlers + * ---------------------------------------------------------------------- */ +static int iascii_int8(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value > CHAR_MAX || *value < CHAR_MIN) return 0; + return 1; +} + +static int iascii_uint8(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value > UCHAR_MAX || *value < 0) return 0; + return 1; +} + +static int iascii_int16(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value > G_MAXINT16 || *value < G_MININT16) return 0; + return 1; +} + +static int iascii_uint16(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value > G_MAXUINT16 || *value < 0) return 0; + return 1; +} + +static int iascii_int32(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value > G_MAXINT32 || *value < G_MININT32) return 0; + return 1; +} + +static int iascii_uint32(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = strtol(BWORD(stl), &end, 10); + if (*end || *value < 0) return 0; + return 1; +} + +static int iascii_float32(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + //fprintf(stderr, "iascii_float32: %s\n", BWORD(stl)); + *value = g_ascii_strtod(BWORD(stl), &end); + if (*end || *value < -FLT_MAX || *value > FLT_MAX) return 0; + return 1; +} + +static int iascii_word(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + //fprintf(stderr, "iascii_word: %s\n", BWORD(stl)); + return 1; +} + +static int iascii_line(p_stl stl, double *value) { + char *end; + size_t t = 0; + if (!stl_read_line(stl)) return 0; + if(strcmp(BLINE(stl), "") == 0){ + if (!stl_read_line(stl)) + return 0; + } + //fprintf(stderr, "iascii_line: '%s'\n", BLINE(stl)); + return 1; +} + + +static int iascii_float64(p_stl stl, double *value) { + char *end; + if (!stl_read_word(stl)) return 0; + *value = g_ascii_strtod(BWORD(stl), &end); + if (*end || *value < -DBL_MAX || *value > DBL_MAX) return 0; + return 1; +} + + + +static int ibinary_int8(p_stl stl, double *value) { + char int8; + if (!stl->idriver->ichunk(stl, &int8, 1)) return 0; + *value = int8; + return 1; +} + +static int ibinary_uint8(p_stl stl, double *value) { + unsigned char uint8; + if (!stl->idriver->ichunk(stl, &uint8, 1)) return 0; + *value = uint8; + return 1; +} + +static int ibinary_int16(p_stl stl, double *value) { + gint16 int16; + if (!stl->idriver->ichunk(stl, &int16, sizeof(int16))) return 0; + *value = int16; + return 1; +} + +static int ibinary_uint16(p_stl stl, double *value) { + guint16 uint16; + if (!stl->idriver->ichunk(stl, &uint16, sizeof(uint16))) return 0; + *value = uint16; + return 1; +} + +static int ibinary_int32(p_stl stl, double *value) { + gint32 int32; + if (!stl->idriver->ichunk(stl, &int32, sizeof(int32))) return 0; + *value = int32; + return 1; +} + +static int ibinary_uint32(p_stl stl, double *value) { + guint32 uint32; + if (!stl->idriver->ichunk(stl, &uint32, sizeof(uint32))) return 0; + *value = uint32; + return 1; +} + +static int ibinary_float32(p_stl stl, double *value) { + float float32; + if (!stl->idriver->ichunk(stl, &float32, sizeof(float32))) return 0; + *value = float32; + //stl_reverse(&float32, sizeof(float32)); + //fprintf(stderr, "ibinary_float32: %f\n", float32); + return 1; +} + +static int ibinary_float64(p_stl stl, double *value) { + return stl->idriver->ichunk(stl, value, sizeof(double)); +} + +/* ---------------------------------------------------------------------- + * Constants + * ---------------------------------------------------------------------- */ +static t_stl_idriver stl_idriver_ascii = { + { iascii_int8, iascii_uint8, iascii_int16, iascii_uint16, + iascii_int32, iascii_uint32, iascii_float32, iascii_float64, + iascii_int8, iascii_uint8, iascii_int16, iascii_uint16, + iascii_int32, iascii_uint32, iascii_float32, iascii_float64, iascii_word, iascii_line + }, /* order matches e_stl_type enum */ + NULL, + "ascii input" +}; + +static t_stl_idriver stl_idriver_binary = { + { ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16, + ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64, + ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16, + ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64 + }, /* order matches e_stl_type enum */ + stl_read_chunk, + "binary input" +}; + +static t_stl_idriver stl_idriver_binary_reverse = { + { ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16, + ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64, + ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16, + ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64 + }, /* order matches e_stl_type enum */ + stl_read_chunk_reverse, + "reverse binary input" +}; + +static t_stl_odriver stl_odriver_ascii = { + { oascii_int8, oascii_uint8, oascii_int16, oascii_uint16, + oascii_int32, oascii_uint32, oascii_float32, oascii_float64, + oascii_int8, oascii_uint8, oascii_int16, oascii_uint16, + oascii_int32, oascii_uint32, oascii_float32, oascii_float64 + }, /* order matches e_stl_type enum */ + NULL, + "ascii output" +}; + +static t_stl_odriver stl_odriver_binary = { + { obinary_int8, obinary_uint8, obinary_int16, obinary_uint16, + obinary_int32, obinary_uint32, obinary_float32, obinary_float64, + obinary_int8, obinary_uint8, obinary_int16, obinary_uint16, + obinary_int32, obinary_uint32, obinary_float32, obinary_float64 + }, /* order matches e_stl_type enum */ + stl_write_chunk, + "binary output" +}; + +static t_stl_odriver stl_odriver_binary_reverse = { + { obinary_int8, obinary_uint8, obinary_int16, obinary_uint16, + obinary_int32, obinary_uint32, obinary_float32, obinary_float64, + obinary_int8, obinary_uint8, obinary_int16, obinary_uint16, + obinary_int32, obinary_uint32, obinary_float32, obinary_float64 + }, /* order matches e_stl_type enum */ + stl_write_chunk_reverse, + "reverse binary output" +}; + +/* ---------------------------------------------------------------------- + * Copyright (C) 2003 Diego Nehab. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ---------------------------------------------------------------------- */ diff --git a/mash/rstl/rstl.h b/mash/rstl/rstl.h new file mode 100644 index 0000000..0c1f630 --- /dev/null +++ b/mash/rstl/rstl.h @@ -0,0 +1,367 @@ +#ifndef STL_H +#define STL_H +/* ---------------------------------------------------------------------- + * RStl library, read/write STL files + * Diego Nehab, Princeton University + * http://www.cs.princeton.edu/~diego/professional/rstl + * + * This library is distributed under the MIT License. See notice + * at the end of this file. + * ---------------------------------------------------------------------- */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RSTL_VERSION "RStl 1.01" +#define RSTL_COPYRIGHT "Copyright (C) 2003-2005 Diego Nehab" +#define RSTL_AUTHORS "Diego Nehab" + +/* ---------------------------------------------------------------------- + * Types + * ---------------------------------------------------------------------- */ +/* structures are opaque */ +typedef struct t_stl_ *p_stl; +typedef struct t_stl_element_ *p_stl_element; +typedef struct t_stl_property_ *p_stl_property; +typedef struct t_stl_argument_ *p_stl_argument; + +/* stl format mode type */ +typedef enum e_stl_storage_mode_ { + STL_BIG_ENDIAN, + STL_LITTLE_ENDIAN, + STL_ASCII, + STL_DEFAULT /* has to be the last in enum */ +} e_stl_storage_mode; /* order matches stl_storage_mode_list */ + +/* stl data type */ +typedef enum e_stl_type { + STL_INT8, STL_UINT8, STL_INT16, STL_UINT16, + STL_INT32, STL_UIN32, STL_FLOAT32, STL_FLOAT64, + STL_CHAR, STL_UCHAR, STL_SHORT, STL_USHORT, + STL_INT, STL_UINT, STL_FLOAT, STL_DOUBLE, STL_WORD, STL_LINE, + STL_LIST /* has to be the last in enum */ +} e_stl_type; /* order matches stl_type_list */ + +/* ---------------------------------------------------------------------- + * Property reading callback prototype + * + * message: error message + * ---------------------------------------------------------------------- */ +typedef void (*p_stl_error_cb)(const char *message, gpointer data); + +/* ---------------------------------------------------------------------- + * Opens a stl file for reading (fails if file is not a stl file) + * + * error_cb: error callback function + * name: file name + * + * Returns 1 if successful, 0 otherwise + * ---------------------------------------------------------------------- */ +p_stl stl_open(const char *name, p_stl_error_cb error_cb, gpointer cb_data); + +/* ---------------------------------------------------------------------- + * Reads and parses the header of a stl file returned by stl_open + * + * stl: handle returned by stl_open + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_read_header(p_stl stl); + +/* ---------------------------------------------------------------------- + * Property reading callback prototype + * + * argument: parameters for property being processed when callback is called + * + * Returns 1 if should continue processing file, 0 if should abort. + * ---------------------------------------------------------------------- */ +typedef int (*p_stl_read_cb)(p_stl_argument argument); + +/* ---------------------------------------------------------------------- + * Sets up callbacks for property reading after header was parsed + * + * stl: handle returned by stl_open + * element_name: element where property is + * property_name: property to associate element with + * read_cb: function to be called for each property value + * pdata/idata: user data that will be passed to callback + * + * Returns 0 if no element or no property in element, returns the + * number of element instances otherwise. + * ---------------------------------------------------------------------- */ +long stl_set_read_cb(p_stl stl, const char *element_name, + const char *property_name, p_stl_read_cb read_cb, + void *pdata, long idata); + +/* ---------------------------------------------------------------------- + * Returns information about the element originating a callback + * + * argument: handle to argument + * element: receives a the element handle (if non-null) + * instance_index: receives the index of the current element instance + * (if non-null) + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_get_argument_element(p_stl_argument argument, + p_stl_element *element, gint32 *instance_index); + +/* ---------------------------------------------------------------------- + * Returns information about the property originating a callback + * + * argument: handle to argument + * property: receives the property handle (if non-null) + * length: receives the number of values in this property (if non-null) + * value_index: receives the index of current property value (if non-null) + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_get_argument_property(p_stl_argument argument, + p_stl_property *property, gint32 *length, gint32 *value_index); + +/* ---------------------------------------------------------------------- + * Returns user data associated with callback + * + * pdata: receives a copy of user custom data pointer (if non-null) + * idata: receives a copy of user custom data integer (if non-null) + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_get_argument_user_data(p_stl_argument argument, void **pdata, + long *idata); + +/* ---------------------------------------------------------------------- + * Returns the value associated with a callback + * + * argument: handle to argument + * + * Returns the current data item + * ---------------------------------------------------------------------- */ +double stl_get_argument_value(p_stl_argument argument); + +/* ---------------------------------------------------------------------- + * Reads all elements and properties calling the callbacks defined with + * calls to stl_set_read_cb + * + * stl: handle returned by stl_open + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_read(p_stl stl); + +/* ---------------------------------------------------------------------- + * Iterates over all elements by returning the next element. + * Call with NULL to return handle to first element. + * + * stl: handle returned by stl_open + * last: handle of last element returned (NULL for first element) + * + * Returns element if successfull or NULL if no more elements + * ---------------------------------------------------------------------- */ +p_stl_element stl_get_next_element(p_stl stl, p_stl_element last); + +/* ---------------------------------------------------------------------- + * Iterates over all comments by returning the next comment. + * Call with NULL to return pointer to first comment. + * + * stl: handle returned by stl_open + * last: pointer to last comment returned (NULL for first comment) + * + * Returns comment if successfull or NULL if no more comments + * ---------------------------------------------------------------------- */ +const char *stl_get_next_comment(p_stl stl, const char *last); + +/* ---------------------------------------------------------------------- + * Iterates over all obj_infos by returning the next obj_info. + * Call with NULL to return pointer to first obj_info. + * + * stl: handle returned by stl_open + * last: pointer to last obj_info returned (NULL for first obj_info) + * + * Returns obj_info if successfull or NULL if no more obj_infos + * ---------------------------------------------------------------------- */ +const char *stl_get_next_obj_info(p_stl stl, const char *last); + +/* ---------------------------------------------------------------------- + * Returns information about an element + * + * element: element of interest + * name: receives a pointer to internal copy of element name (if non-null) + * ninstances: receives the number of instances of this element (if non-null) + * + * Returns 1 if successfull or 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_get_element_info(p_stl_element element, const char** name, + gint32 *ninstances); + +/* ---------------------------------------------------------------------- + * Iterates over all properties by returning the next property. + * Call with NULL to return handle to first property. + * + * element: handle of element with the properties of interest + * last: handle of last property returned (NULL for first property) + * + * Returns element if successfull or NULL if no more properties + * ---------------------------------------------------------------------- */ +p_stl_property stl_get_next_property(p_stl_element element, + p_stl_property last); + +/* ---------------------------------------------------------------------- + * Returns information about a property + * + * property: handle to property of interest + * name: receives a pointer to internal copy of property name (if non-null) + * type: receives the property type (if non-null) + * length_type: for list properties, receives the scalar type of + * the length field (if non-null) + * value_type: for list properties, receives the scalar type of the value + * fields (if non-null) + * + * Returns 1 if successfull or 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_get_property_info(p_stl_property property, const char** name, + e_stl_type *type, e_stl_type *length_type, e_stl_type *value_type); + +/* ---------------------------------------------------------------------- + * Creates new stl file + * + * name: file name + * storage_mode: file format mode + * + * Returns handle to stl file if successfull, NULL otherwise + * ---------------------------------------------------------------------- */ +p_stl stl_create(const char *name, e_stl_storage_mode storage_mode, + p_stl_error_cb error_cb, gpointer cb_data); + +/* ---------------------------------------------------------------------- + * Adds a new element to the stl file created by stl_create + * + * stl: handle returned by stl_create + * name: name of new element + * ninstances: number of element of this time in file + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_element(p_stl stl, const char *name, gint32 ninstances); + +/* ---------------------------------------------------------------------- + * Adds a new property to the last element added by stl_add_element + * + * stl: handle returned by stl_create + * name: name of new property + * type: property type + * length_type: scalar type of length field of a list property + * value_type: scalar type of value fields of a list property + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_property(p_stl stl, const char *name, e_stl_type type, + e_stl_type length_type, e_stl_type value_type); + +/* ---------------------------------------------------------------------- + * Adds a new list property to the last element added by stl_add_element + * + * stl: handle returned by stl_create + * name: name of new property + * length_type: scalar type of length field of a list property + * value_type: scalar type of value fields of a list property + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_list_property(p_stl stl, const char *name, + e_stl_type length_type, e_stl_type value_type); + +/* ---------------------------------------------------------------------- + * Adds a new property to the last element added by stl_add_element + * + * stl: handle returned by stl_create + * name: name of new property + * type: property type + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_scalar_property(p_stl stl, const char *name, e_stl_type type); + +/* ---------------------------------------------------------------------- + * Adds a new comment item + * + * stl: handle returned by stl_create + * comment: pointer to string with comment text + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_comment(p_stl stl, const char *comment); + +/* ---------------------------------------------------------------------- + * Adds a new obj_info item + * + * stl: handle returned by stl_create + * comment: pointer to string with obj_info data + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_add_obj_info(p_stl stl, const char *obj_info); + +/* ---------------------------------------------------------------------- + * Writes the stl file header after all element and properties have been + * defined by calls to stl_add_element and stl_add_property + * + * stl: handle returned by stl_create + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_write_header(p_stl stl); + +/* ---------------------------------------------------------------------- + * Writes one property value, in the order they should be written to the + * file. For each element type, write all elements of that type in order. + * For each element, write all its properties in order. For scalar + * properties, just write the value. For list properties, write the length + * and then each of the values. + * + * stl: handle returned by stl_create + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_write(p_stl stl, double value); + +/* ---------------------------------------------------------------------- + * Closes a stl file handle. Releases all memory used by handle + * + * stl: handle to be closed. + * + * Returns 1 if successfull, 0 otherwise + * ---------------------------------------------------------------------- */ +int stl_close(p_stl stl); + +#ifdef __cplusplus +} +#endif + +#endif /* RSTL_H */ + +/* ---------------------------------------------------------------------- + * Copyright (C) 2003-2005 Diego Nehab. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ---------------------------------------------------------------------- */